diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-12-19 01:01:11 +0100 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2021-12-22 00:02:36 -0800 |
commit | ce1bf3724e30e1ea5669ed7fe9fcbf5e9d423493 (patch) | |
tree | 1623bea659ddf54259868f33197d77addab2ce6b /Kernel | |
parent | fd3be7ffccc18b92dace3e8f26489b99e0c4cce7 (diff) | |
download | serenity-ce1bf3724e30e1ea5669ed7fe9fcbf5e9d423493.zip |
Kernel: Replace intersecting ranges in mmap when MAP_FIXED is specified
This behavior is mandated by POSIX and is used by software like Wine
after reserving large chunks of the address range.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Syscalls/mmap.cpp | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index 4fc530b66a..b4e901cd75 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -189,11 +189,16 @@ ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> use if (map_randomized) { return address_space().page_directory().range_allocator().try_allocate_randomized(Memory::page_round_up(size), alignment); } + auto range = address_space().try_allocate_range(VirtualAddress(addr), size, alignment); if (range.is_error()) { if (addr && !map_fixed) { // If there's an address but MAP_FIXED wasn't specified, the address is just a hint. range = address_space().try_allocate_range({}, size, alignment); + } else if (map_fixed) { + // If MAP_FIXED is specified, existing mappings that intersect the requested range are removed. + TRY(address_space().unmap_mmap_range(VirtualAddress(addr), size)); + range = address_space().try_allocate_range(VirtualAddress(addr), size, alignment); } } return range; |