summaryrefslogtreecommitdiff
path: root/Kernel/VM
AgeCommit message (Collapse)Author
2020-02-16Kernel: Reduce header dependencies of MemoryManager and RegionAndreas Kling
2020-02-16Kernel: Move all code into the Kernel namespaceAndreas Kling
2020-02-15Kernel: Widen PhysicalPage refcount to 32 bitsAndreas Kling
A 16-bit refcount is just begging for trouble right nowl. A 32-bit refcount will be begging for trouble later down the line, so we'll have to revisit this eventually. :^)
2020-02-15Kernel: Use a shared physical page for zero-filled pages until writtenAndreas Kling
This patch adds a globally shared zero-filled PhysicalPage that will be mapped into every slot of every zero-filled AnonymousVMObject until that page is written to, achieving CoW-like zero-filled pages. Initial testing show that this doesn't actually achieve any sharing yet but it seems like a good design regardless, since it may reduce the number of page faults taken by programs. If you look at the refcount of MM.shared_zero_page() it will have quite a high refcount, but that's just because everything maps it everywhere. If you want to see the "real" refcount, you can build with the MAP_SHARED_ZERO_PAGE_LAZILY flag, and we'll defer mapping of the shared zero page until the first NP read fault. I've left this behavior behind a flag for future testing of this code.
2020-02-10Kernel: Add getter and setter for the X86 CR3 registerAndreas Kling
This gets rid of a bunch of inline assembly.
2020-02-10Kernel: Remove more <LibBareMetal/Output/kstdio.h> includesAndreas Kling
2020-02-10AK: Remove bitrotted Traits::dump() mechanismAndreas Kling
This was only used by HashTable::dump() which I used when doing the first HashTable implementation. Removing this allows us to also remove most includes of <AK/kstdio.h>.
2020-02-09Kernel: Use VirtualAddress & PhysicalAddress classes from LibBareMetalLiav A
2020-02-09Kernel: Apply changes to use LibBareMetal definitionsLiav A
2020-02-08Kernel: The inode fault handler should grab the VMObject lock earlierAndreas Kling
It doesn't look healthy to create raw references into an array before a temporary unlock. In fact, that temporary unlock looks generally unhealthy, but it's a different problem.
2020-02-08x86: Simplify region unmapping a bitAndreas Kling
Add PageTableEntry::clear() to zero out a whole PTE, and use that for unmapping instead of clearing individual fields.
2020-02-08Kernel: Cloned shared regions should also be marked as sharedAndreas Kling
2020-01-30Kernel: Add some sanity assertions in RangeAllocator::deallocate()Andreas Kling
We should never end up deallocating an empty range, or a range that ends before it begins.
2020-01-30Kernel: Range::contains() should reject ranges with 2^32 wrap-aroundAndreas Kling
2020-01-29Kernel: Fail with EFAULT for any address+size that would wrap aroundAndreas Kling
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.
2020-01-28Kernel: AnonymousVMObject::create_for_physical_range() should fail moreAndreas Kling
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
2020-01-28Kernel: Remove outdated comment in MemoryManagerAndreas Kling
Regions *do* zero-fill on demand now. :^)
2020-01-23AK: Let's call decrementing reference counts "unref" instead of "deref"Andreas Kling
It always bothered me that we're using the overloaded "dereference" term for this. Let's call it "unreference" instead. :^)
2020-01-21Kernel: Tidy up debug logging a little bitAndreas Kling
When using dbg() in the kernel, the output is automatically prefixed with [Process(PID:TID)]. This makes it a lot easier to understand which thread is generating the output. This patch also cleans up some common logging messages and removes the now-unnecessary "dbg() << *current << ..." pattern.
2020-01-21Kernel: Remove map_for_kernel() in MemoryManagerLiav A
We don't need to have this method anymore. It was a hack that was used in many components in the system but currently we use better methods to create virtual memory mappings. To prevent any further use of this method it's best to just remove it completely. Also, the APIC code is disabled for now since it doesn't help booting the system, and is broken since it relies on identity mapping to exist in the first 1MB. Any call to the APIC code will result in assertion failed. In addition to that, the name of the method which is responsible to create an identity mapping between 1MB to 2MB was changed, to be more precise about its purpose.
2020-01-20Add AnonymousVMObject::create_with_physical_page()Andreas Kling
This can be used to create a VMObject for a single PhysicalPage.
2020-01-20Kernel: Write-only regions should still be mapped as presentAndreas Kling
There is no real "read protection" on x86, so we have no choice but to map write-only pages simply as "present & read/write". If we get a read page fault in a non-readable region, that's still a correctness issue, so we crash the process. It's by no means a complete protection against invalid reads, since it's trivial to fool the kernel by first causing a write fault in the same region.
2020-01-20Kernel: Remove some unnecessary casts to uintptr_tAndreas Kling
VirtualAddress is constructible from uintptr_t and const void*. PhysicalAddress is constructible from uintptr_t but not const void*.
2020-01-20Use uintptr_t instead of u32 when storing pointers as integersAndreas Kling
uintptr_t is 32-bit or 64-bit depending on the target platform. This will help us write pointer size agnostic code so that when the day comes that we want to do a 64-bit port, we'll be in better shape.
2020-01-19Kernel: Oops, fix bad sort order of available VM rangesAndreas Kling
This made the allocator perform worse, so here's another second off of the Kernel/Process.cpp compile time from a simple bugfix! (31s to 30s)
2020-01-19Kernel: Make ProcessPagingScope restore CR3 properlyAndreas Kling
Instead of restoring CR3 to the current process's paging scope when a ProcessPagingScope goes out of scope, we now restore exactly whatever the CR3 value was when we created the ProcessPagingScope. This fixes breakage in situations where a process ends up with nested ProcessPagingScopes. This was making profiling very fragile, and with this change it's now possible to profile g++! :^)
2020-01-19Kernel: Optimize VM range deallocation a bitAndreas Kling
Previously, when deallocating a range of VM, we would sort and merge the range list. This was quite slow for large processes. This patch optimizes VM deallocation in the following ways: - Use binary search instead of linear scan to find the place to insert the deallocated range. - Insert at the right place immediately, removing the need to sort. - Merge the inserted range with any adjacent range(s) in-line instead of doing a separate merge pass into a list copy. - Add Traits<Range> to inform Vector that Range objects are trivial and can be moved using memmove(). I've also added an assertion that deallocated ranges are actually part of the RangeAllocator's initial address range. I've benchmarked this using g++ to compile Kernel/Process.cpp. With these changes, compilation goes from ~41 sec to ~35 sec.
2020-01-19Kernel: Assert that copy_to/from_user() are called with user addressesAndreas Kling
This will panic the kernel immediately if these functions are misused so we can catch it and fix the misuse. This patch fixes a couple of misuses: - create_signal_trampolines() writes to a user-accessible page above the 3GB address mark. We should really get rid of this page but that's a whole other thing. - CoW faults need to use copy_from_user rather than copy_to_user since it's the *source* pointer that points to user memory. - Inode faults need to use memcpy rather than copy_to_user since we're copying a kernel stack buffer into a quickmapped page. This should make the copy_to/from_user() functions slightly less useful for exploitation. Before this, they were essentially just glorified memcpy() with SMAP disabled. :^)
2020-01-19Kernel: Let's say that everything < 3GB is user virtual memoryAndreas Kling
Technically the bottom 2MB is still identity-mapped for the kernel and not made available to userspace at all, but for simplicity's sake we can just ignore that and make "address < 0xc0000000" the canonical check for user/kernel.
2020-01-18Kernel: Enforce W^X between sys$mmap() and sys$execve()Andreas Kling
It's now an error to sys$mmap() a file as writable if it's currently mapped executable by anyone else. It's also an error to sys$execve() a file that's currently mapped writable by anyone else. This fixes a race condition vulnerability where one program could make modifications to an executable while another process was in the kernel, in the middle of exec'ing the same executable. Test: Kernel/elf-execve-mmap-race.cpp
2020-01-18Kernel: Move all CPU feature initialization into cpu_setup()Andreas Kling
..and do it very very early in boot.
2020-01-18Meta: Add license header to source filesAndreas Kling
As suggested by Joshua, this commit adds the 2-clause BSD license as a comment block to the top of every source file. For the first pass, I've just added myself for simplicity. I encourage everyone to add themselves as copyright holders of any file they've added or modified in some significant way. If I've added myself in error somewhere, feel free to replace it with the appropriate copyright holder instead. Going forward, all new source files should include a license header.
2020-01-18Kernel: Always dump kernel regions when dumping process regionsAndreas Kling
2020-01-18Kernel: Remove two unused MemoryManager functionsAndreas Kling
2020-01-18Kernel: Clean up MemoryManager initialization a bit moreAndreas Kling
Move the CPU feature enabling to functions in Arch/i386/CPU.cpp.
2020-01-17Kernel: Add a random offset to the base of the per-process VM allocatorAndreas Kling
This is not ASLR, but it does de-trivialize exploiting the ELF loader which would previously always parse executables at 0x01001000 in every single exec(). I've taken advantage of this multiple times in my own toy exploits and it's starting to feel cheesy. :^)
2020-01-17Kernel: Only clone the bottom 2MB of mappings from kernel to processesAndreas Kling
2020-01-17Kernel: Don't allocate per-process PDPT from super pages eitherAndreas Kling
The default system is now down to 3 super pages allocated on boot. :^)
2020-01-17Kernel: Stop allocating page tables from the super pages poolAndreas Kling
We now use the regular "user" physical pages for on-demand page table allocations. This was by far the biggest source of super physical page exhaustion, so that bug should be a thing of the past now. :^) We still have super pages, but they are barely used. They remain useful for code that requires memory with a low physical address. Fixes #1000.
2020-01-17Kernel: Re-enable protection of the kernel image in memoryAndreas Kling
2020-01-17Kernel: Tidy up the lowest part of the address spaceAndreas Kling
After MemoryManager initialization, we now only leave the lowest 1MB of memory identity-mapped. The very first (null) page is not present. All other pages are RW but not X. Supervisor only.
2020-01-17Kernel: Tidy up the types imported from boot.S a little bitAndreas Kling
2020-01-17Kernel: Move Multiboot memory map parsing to its own functionAndreas Kling
2020-01-17Kernel: Clean up ensure_pte()Andreas Kling
2020-01-17Kernel: Move kernel above the 3GB virtual address markAndreas Kling
The kernel and its static data structures are no longer identity-mapped in the bottom 8MB of the address space, but instead move above 3GB. The first 8MB above 3GB are pseudo-identity-mapped to the bottom 8MB of the physical address space. But things don't have to stay this way! Thanks to Jesse who made an earlier attempt at this, it was really easy to get device drivers working once the page tables were in place! :^) Fixes #734.
2020-01-14Kernel: Change Region allocation helpersLiav A
We now can create a cacheable Region, so when map() is called, if a Region is cacheable then all the virtual memory space being allocated to it will be marked as not cache disabled. In addition to that, OS components can create a Region that will be mapped to a specific physical address by using the appropriate helper method.
2020-01-10Kernel: Copy Region's "is_mmap" flag when cloning regions for fork()Andreas Kling
Otherwise child processes will not be allowed to munmap(), madvise(), etc. on the cloned regions!
2020-01-10Kernel: Page allocation should not use memset_user() when zeroingAndreas Kling
We're not zeroing new pages through a userspace address, so this should not use memset_user().
2020-01-10Kernel+LibELF: Enable SMAP protection during non-syscall exec()Andreas Kling
When loading a new executable, we now map the ELF image in kernel-only memory and parse it there. Then we use copy_to_user() when initializing writable regions with data from the executable. Note that the exec() syscall still disables SMAP protection and will require additional work. This patch only affects kernel-originated process spawns.
2020-01-06Kernel: Harden memory mapping of the kernel imageAndreas Kling
We now map the kernel's text and rodata segments read+execute. We also make the data and bss segments non-executable. Thanks to q3k for the idea! :^)