mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
Kernel: Fail with EFAULT for any address+size that would wrap around
Previously we were only checking that each of the virtual pages in the specified range were valid. This made it possible to pass in negative buffer sizes to some syscalls as long as (address) and (address+size) were on the same page.
This commit is contained in:
parent
03837e37a3
commit
a27c5d2fb7
Notes:
sideshowbarker
2024-07-19 09:45:15 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/a27c5d2fb7e
2 changed files with 16 additions and 0 deletions
|
@ -569,6 +569,11 @@ template<MemoryManager::AccessSpace space, MemoryManager::AccessType access_type
|
||||||
bool MemoryManager::validate_range(const Process& process, VirtualAddress base_vaddr, size_t size) const
|
bool MemoryManager::validate_range(const Process& process, VirtualAddress base_vaddr, size_t size) const
|
||||||
{
|
{
|
||||||
ASSERT(size);
|
ASSERT(size);
|
||||||
|
if (base_vaddr > base_vaddr.offset(size)) {
|
||||||
|
dbg() << "Shenanigans! Asked to validate wrappy " << base_vaddr << " size=" << size;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
VirtualAddress vaddr = base_vaddr.page_base();
|
VirtualAddress vaddr = base_vaddr.page_base();
|
||||||
VirtualAddress end_vaddr = base_vaddr.offset(size - 1).page_base();
|
VirtualAddress end_vaddr = base_vaddr.offset(size - 1).page_base();
|
||||||
if (end_vaddr < vaddr) {
|
if (end_vaddr < vaddr) {
|
||||||
|
|
|
@ -47,6 +47,14 @@
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define EXPECT_EFAULT_NO_FD(syscall, address, size) \
|
||||||
|
do { \
|
||||||
|
rc = syscall((address), (size_t)(size)); \
|
||||||
|
if (rc >= 0 || errno != EFAULT) { \
|
||||||
|
fprintf(stderr, "Expected EFAULT: " #syscall "(%p, %zu), got rc=%d, errno=%d\n", (void*)(address), (size_t)(size), rc, errno); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
|
@ -81,6 +89,9 @@ int main(int, char**)
|
||||||
EXPECT_EFAULT(read, (void*)kernel_address, 1);
|
EXPECT_EFAULT(read, (void*)kernel_address, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char buffer[4096];
|
||||||
|
EXPECT_EFAULT_NO_FD(dbgputstr, buffer, 0xffffff00);
|
||||||
|
|
||||||
// Test the page just below where the kernel VM begins.
|
// Test the page just below where the kernel VM begins.
|
||||||
u8* jerk_page = (u8*)mmap((void*)(0xc0000000 - PAGE_SIZE), PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
|
u8* jerk_page = (u8*)mmap((void*)(0xc0000000 - PAGE_SIZE), PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
|
||||||
ASSERT(jerk_page == (void*)(0xc0000000 - PAGE_SIZE));
|
ASSERT(jerk_page == (void*)(0xc0000000 - PAGE_SIZE));
|
||||||
|
|
Loading…
Reference in a new issue