diff options
author | Andreas Kling <kling@serenityos.org> | 2020-01-28 20:48:07 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-01-28 20:48:07 +0100 |
commit | c17f80e720b269e88700af4ea13f877b6d72303b (patch) | |
tree | ac5327d746b197c0d2c10015d302964bd09e89d2 /Kernel/VM/MemoryManager.cpp | |
parent | bd059e32e14fa4ee6b498be4cc50ae678040d1d4 (diff) | |
download | serenity-c17f80e720b269e88700af4ea13f877b6d72303b.zip |
Kernel: AnonymousVMObject::create_for_physical_range() should fail more
Previously it was not possible for this function to fail. You could
exploit this by triggering the creation of a VMObject whose physical
memory range would wrap around the 32-bit limit.
It was quite easy to map kernel memory into userspace and read/write
whatever you wanted in it.
Test: Kernel/bxvga-mmap-kernel-into-userspace.cpp
Diffstat (limited to 'Kernel/VM/MemoryManager.cpp')
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index db877a128e..9053f201f3 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -313,11 +313,14 @@ OwnPtr<Region> MemoryManager::allocate_kernel_region(PhysicalAddress paddr, size ASSERT(!(size % PAGE_SIZE)); auto range = kernel_page_directory().range_allocator().allocate_anywhere(size); ASSERT(range.is_valid()); + auto vmobject = AnonymousVMObject::create_for_physical_range(paddr, size); + if (!vmobject) + return nullptr; OwnPtr<Region> region; if (user_accessible) - region = Region::create_user_accessible(range, AnonymousVMObject::create_for_physical_range(paddr, size), 0, name, access, cacheable); + region = Region::create_user_accessible(range, vmobject.release_nonnull(), 0, name, access, cacheable); else - region = Region::create_kernel_only(range, AnonymousVMObject::create_for_physical_range(paddr, size), 0, name, access, cacheable); + region = Region::create_kernel_only(range, vmobject.release_nonnull(), 0, name, access, cacheable); region->map(kernel_page_directory()); return region; } |