mprotect(): Validate the entire range to protect is in userspace memory
Before this patch, sys_mprotect() only validated the starting address. This was as bad as it sounds, in fact it let me write a fun exploit using it. Now, this exploit is no longer possible. This patch is probably not relevant, since this branch will be gone in the future, as soon as restart gets merged into main. I made it anyways :^)
This commit is contained in:
parent
1f4c4f1a0c
commit
4ef764e62e
@ -45,10 +45,10 @@ uint64_t Memory::get_usable()
|
||||
|
||||
bool Memory::is_kernel_address(uintptr_t address)
|
||||
{
|
||||
return address >= 0xfffffffff8000000;
|
||||
return address >= 0xffff800000000000;
|
||||
}
|
||||
|
||||
bool Memory::is_user_address(uintptr_t address)
|
||||
{
|
||||
return address && address < 0xfffffffff8000000;
|
||||
return address && address < 0x00007fffffffffff;
|
||||
}
|
@ -55,9 +55,9 @@ void sys_mmap(Context* context, void* address, size_t size, int prot, int fd, of
|
||||
if (address)
|
||||
{
|
||||
kdbgln("mmap(): %ld pages at address %p, %s, fd %d", size / PAGE_SIZE, address, format_prot(prot), fd);
|
||||
if (Memory::is_kernel_address((uintptr_t)address))
|
||||
if (!Memory::is_user_address((uintptr_t)address))
|
||||
{
|
||||
kwarnln("munmap() failed: attempted to unmap a kernel page");
|
||||
kwarnln("mmap() failed: attempted to map a non-user page");
|
||||
context->rax = MAP_FAIL(ENOMEM);
|
||||
return;
|
||||
}
|
||||
@ -153,9 +153,9 @@ void sys_munmap(Context* context, void* address, size_t size)
|
||||
context->rax = -EINVAL;
|
||||
return;
|
||||
}
|
||||
if (Memory::is_kernel_address((uintptr_t)address))
|
||||
if (!Memory::is_user_address((uintptr_t)address))
|
||||
{
|
||||
kwarnln("munmap() failed: attempted to unmap a kernel page");
|
||||
kwarnln("munmap() failed: attempted to unmap a non-user page");
|
||||
context->rax = -EINVAL;
|
||||
return;
|
||||
}
|
||||
@ -202,9 +202,16 @@ void sys_mprotect(Context* context, void* address, size_t size, int prot)
|
||||
context->rax = -EINVAL;
|
||||
return;
|
||||
}
|
||||
if (Memory::is_kernel_address((uintptr_t)address))
|
||||
if (!Memory::is_user_address((uintptr_t)address))
|
||||
{
|
||||
kwarnln("mprotect() failed: attempted to protect a kernel page");
|
||||
kwarnln("mprotect() failed: attempted to protect a non-user page");
|
||||
context->rax = -EINVAL;
|
||||
return;
|
||||
}
|
||||
// FIXME: Check for overflow when adding address + size.
|
||||
if (!Memory::is_user_address((uintptr_t)address + size))
|
||||
{
|
||||
kwarnln("mprotect() failed: end of given range is out of user memory");
|
||||
context->rax = -EINVAL;
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user