Merge pull request #1967 from lioncash/thread

kernel/svc: Sanitize core and priority masks within CreateThread
This commit is contained in:
bunnei 2018-12-31 11:10:05 -05:00 committed by GitHub
commit 09ffa0cb21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 24 deletions

View file

@ -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();
} }

View file

@ -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,