1
0
Fork 0
forked from suyu/suyu

Merge pull request #1520 from lioncash/san

svc: Add missing sanitizing checks for MapSharedMemory/UnmapSharedMemory
This commit is contained in:
bunnei 2018-10-19 22:58:57 -04:00 committed by GitHub
commit 60317e6306
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 3 deletions

View file

@ -584,6 +584,10 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
return ERR_INVALID_SIZE; return ERR_INVALID_SIZE;
} }
if (!IsValidAddressRange(addr, size)) {
return ERR_INVALID_ADDRESS_STATE;
}
const auto permissions_type = static_cast<MemoryPermission>(permissions); const auto permissions_type = static_cast<MemoryPermission>(permissions);
if (permissions_type != MemoryPermission::Read && if (permissions_type != MemoryPermission::Read &&
permissions_type != MemoryPermission::ReadWrite) { permissions_type != MemoryPermission::ReadWrite) {
@ -597,8 +601,14 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }
return shared_memory->Map(Core::CurrentProcess(), addr, permissions_type, auto* const current_process = Core::CurrentProcess();
MemoryPermission::DontCare); const auto& vm_manager = current_process->VMManager();
if (!vm_manager.IsWithinASLRRegion(addr, size)) {
return ERR_INVALID_MEMORY_RANGE;
}
return shared_memory->Map(current_process, addr, permissions_type, MemoryPermission::DontCare);
} }
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
@ -613,10 +623,24 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
return ERR_INVALID_SIZE; return ERR_INVALID_SIZE;
} }
if (!IsValidAddressRange(addr, size)) {
return ERR_INVALID_ADDRESS_STATE;
}
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle); auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
if (!shared_memory) {
return ERR_INVALID_HANDLE;
}
return shared_memory->Unmap(Core::CurrentProcess(), addr); auto* const current_process = Core::CurrentProcess();
const auto& vm_manager = current_process->VMManager();
if (!vm_manager.IsWithinASLRRegion(addr, size)) {
return ERR_INVALID_MEMORY_RANGE;
}
return shared_memory->Unmap(current_process, addr);
} }
/// Query process memory /// Query process memory

View file

@ -507,6 +507,26 @@ u64 VMManager::GetASLRRegionSize() const {
return aslr_region_end - aslr_region_base; return aslr_region_end - aslr_region_base;
} }
bool VMManager::IsWithinASLRRegion(VAddr begin, u64 size) const {
const VAddr range_end = begin + size;
const VAddr aslr_start = GetASLRRegionBaseAddress();
const VAddr aslr_end = GetASLRRegionEndAddress();
if (aslr_start > begin || begin > range_end || range_end - 1 > aslr_end - 1) {
return false;
}
if (range_end > heap_region_base && heap_region_end > begin) {
return false;
}
if (range_end > map_region_base && map_region_end > begin) {
return false;
}
return true;
}
VAddr VMManager::GetCodeRegionBaseAddress() const { VAddr VMManager::GetCodeRegionBaseAddress() const {
return code_region_base; return code_region_base;
} }

View file

@ -211,6 +211,9 @@ public:
/// Gets the end address of the ASLR region. /// Gets the end address of the ASLR region.
VAddr GetASLRRegionEndAddress() const; VAddr GetASLRRegionEndAddress() const;
/// Determines whether or not the specified address range is within the ASLR region.
bool IsWithinASLRRegion(VAddr address, u64 size) const;
/// Gets the size of the ASLR region /// Gets the size of the ASLR region
u64 GetASLRRegionSize() const; u64 GetASLRRegionSize() const;