kernel/svc: Sanitize addresses, permissions, and sizes within svcMapSharedMemory() and svcUnmapSharedMemory()
Part of the checking done by the kernel is to check if the given address and size are 4KB aligned, as well as checking if the size isn't zero. It also only allows mapping shared memory as readable or read/write, but nothing else, and so we shouldn't allow mapping as anything else either.
This commit is contained in:
parent
496c67fd73
commit
accd1f17e4
1 changed files with 25 additions and 17 deletions
|
@ -444,35 +444,43 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
|
||||||
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||||
shared_memory_handle, addr, size, permissions);
|
shared_memory_handle, addr, size, permissions);
|
||||||
|
|
||||||
|
if (!Is4KBAligned(addr)) {
|
||||||
|
return ERR_INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0 || !Is4KBAligned(size)) {
|
||||||
|
return ERR_INVALID_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto permissions_type = static_cast<MemoryPermission>(permissions);
|
||||||
|
if (permissions_type != MemoryPermission::Read &&
|
||||||
|
permissions_type != MemoryPermission::ReadWrite) {
|
||||||
|
LOG_ERROR(Kernel_SVC, "Invalid permissions=0x{:08X}", permissions);
|
||||||
|
return ERR_INVALID_MEMORY_PERMISSIONS;
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
if (!shared_memory) {
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions);
|
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
|
||||||
switch (permissions_type) {
|
MemoryPermission::DontCare);
|
||||||
case MemoryPermission::Read:
|
|
||||||
case MemoryPermission::Write:
|
|
||||||
case MemoryPermission::ReadWrite:
|
|
||||||
case MemoryPermission::Execute:
|
|
||||||
case MemoryPermission::ReadExecute:
|
|
||||||
case MemoryPermission::WriteExecute:
|
|
||||||
case MemoryPermission::ReadWriteExecute:
|
|
||||||
case MemoryPermission::DontCare:
|
|
||||||
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
|
|
||||||
MemoryPermission::DontCare);
|
|
||||||
default:
|
|
||||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
|
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
|
||||||
LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
|
LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
|
||||||
shared_memory_handle, addr, size);
|
shared_memory_handle, addr, size);
|
||||||
|
|
||||||
|
if (!Is4KBAligned(addr)) {
|
||||||
|
return ERR_INVALID_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0 || !Is4KBAligned(size)) {
|
||||||
|
return ERR_INVALID_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue