Merge pull request #1967 from lioncash/thread
kernel/svc: Sanitize core and priority masks within CreateThread
This commit is contained in:
commit
09ffa0cb21
|
@ -173,13 +173,13 @@ public:
|
||||||
return ideal_core;
|
return ideal_core;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the bitmask of allowed CPUs that this process' threads can run on.
|
/// Gets the bitmask of allowed cores that this process' threads can run on.
|
||||||
u64 GetAllowedProcessorMask() const {
|
u64 GetCoreMask() const {
|
||||||
return capabilities.GetCoreMask();
|
return capabilities.GetCoreMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the bitmask of allowed thread priorities.
|
/// Gets the bitmask of allowed thread priorities.
|
||||||
u64 GetAllowedThreadPriorityMask() const {
|
u64 GetPriorityMask() const {
|
||||||
return capabilities.GetPriorityMask();
|
return capabilities.GetPriorityMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -715,8 +715,8 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||||
|
|
||||||
enum class GetInfoType : u64 {
|
enum class GetInfoType : u64 {
|
||||||
// 1.0.0+
|
// 1.0.0+
|
||||||
AllowedCpuIdBitmask = 0,
|
AllowedCPUCoreMask = 0,
|
||||||
AllowedThreadPrioBitmask = 1,
|
AllowedThreadPriorityMask = 1,
|
||||||
MapRegionBaseAddr = 2,
|
MapRegionBaseAddr = 2,
|
||||||
MapRegionSize = 3,
|
MapRegionSize = 3,
|
||||||
HeapRegionBaseAddr = 4,
|
HeapRegionBaseAddr = 4,
|
||||||
|
@ -747,8 +747,8 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||||
const auto info_id_type = static_cast<GetInfoType>(info_id);
|
const auto info_id_type = static_cast<GetInfoType>(info_id);
|
||||||
|
|
||||||
switch (info_id_type) {
|
switch (info_id_type) {
|
||||||
case GetInfoType::AllowedCpuIdBitmask:
|
case GetInfoType::AllowedCPUCoreMask:
|
||||||
case GetInfoType::AllowedThreadPrioBitmask:
|
case GetInfoType::AllowedThreadPriorityMask:
|
||||||
case GetInfoType::MapRegionBaseAddr:
|
case GetInfoType::MapRegionBaseAddr:
|
||||||
case GetInfoType::MapRegionSize:
|
case GetInfoType::MapRegionSize:
|
||||||
case GetInfoType::HeapRegionBaseAddr:
|
case GetInfoType::HeapRegionBaseAddr:
|
||||||
|
@ -774,12 +774,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info_id_type) {
|
switch (info_id_type) {
|
||||||
case GetInfoType::AllowedCpuIdBitmask:
|
case GetInfoType::AllowedCPUCoreMask:
|
||||||
*result = process->GetAllowedProcessorMask();
|
*result = process->GetCoreMask();
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
|
|
||||||
case GetInfoType::AllowedThreadPrioBitmask:
|
case GetInfoType::AllowedThreadPriorityMask:
|
||||||
*result = process->GetAllowedThreadPriorityMask();
|
*result = process->GetPriorityMask();
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
|
|
||||||
case GetInfoType::MapRegionBaseAddr:
|
case GetInfoType::MapRegionBaseAddr:
|
||||||
|
@ -1219,12 +1219,6 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
|
||||||
"threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
|
"threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
|
||||||
entry_point, arg, stack_top, priority, processor_id, *out_handle);
|
entry_point, arg, stack_top, priority, processor_id, *out_handle);
|
||||||
|
|
||||||
if (priority > THREADPRIO_LOWEST) {
|
|
||||||
LOG_ERROR(Kernel_SVC, "An invalid priority was specified, expected {} but got {}",
|
|
||||||
THREADPRIO_LOWEST, priority);
|
|
||||||
return ERR_INVALID_THREAD_PRIORITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* const current_process = Core::CurrentProcess();
|
auto* const current_process = Core::CurrentProcess();
|
||||||
|
|
||||||
if (processor_id == THREADPROCESSORID_IDEAL) {
|
if (processor_id == THREADPROCESSORID_IDEAL) {
|
||||||
|
@ -1233,17 +1227,29 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
|
||||||
ASSERT(processor_id != THREADPROCESSORID_IDEAL);
|
ASSERT(processor_id != THREADPROCESSORID_IDEAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (processor_id) {
|
if (processor_id < THREADPROCESSORID_0 || processor_id > THREADPROCESSORID_3) {
|
||||||
case THREADPROCESSORID_0:
|
|
||||||
case THREADPROCESSORID_1:
|
|
||||||
case THREADPROCESSORID_2:
|
|
||||||
case THREADPROCESSORID_3:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR(Kernel_SVC, "Invalid thread processor ID: {}", processor_id);
|
LOG_ERROR(Kernel_SVC, "Invalid thread processor ID: {}", processor_id);
|
||||||
return ERR_INVALID_PROCESSOR_ID;
|
return ERR_INVALID_PROCESSOR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u64 core_mask = current_process->GetCoreMask();
|
||||||
|
if ((core_mask | (1ULL << processor_id)) != core_mask) {
|
||||||
|
LOG_ERROR(Kernel_SVC, "Invalid thread core specified ({})", processor_id);
|
||||||
|
return ERR_INVALID_PROCESSOR_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priority > THREADPRIO_LOWEST) {
|
||||||
|
LOG_ERROR(Kernel_SVC,
|
||||||
|
"Invalid thread priority specified ({}). Must be within the range 0-64",
|
||||||
|
priority);
|
||||||
|
return ERR_INVALID_THREAD_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((1ULL << priority) & current_process->GetPriorityMask()) == 0) {
|
||||||
|
LOG_ERROR(Kernel_SVC, "Invalid thread priority specified ({})", priority);
|
||||||
|
return ERR_INVALID_THREAD_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string name = fmt::format("thread-{:X}", entry_point);
|
const std::string name = fmt::format("thread-{:X}", entry_point);
|
||||||
auto& kernel = Core::System::GetInstance().Kernel();
|
auto& kernel = Core::System::GetInstance().Kernel();
|
||||||
CASCADE_RESULT(SharedPtr<Thread> thread,
|
CASCADE_RESULT(SharedPtr<Thread> thread,
|
||||||
|
|
Reference in New Issue