summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2021-12-19 01:01:11 +0100
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-12-22 00:02:36 -0800
commitce1bf3724e30e1ea5669ed7fe9fcbf5e9d423493 (patch)
tree1623bea659ddf54259868f33197d77addab2ce6b /Kernel
parentfd3be7ffccc18b92dace3e8f26489b99e0c4cce7 (diff)
downloadserenity-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.cpp5
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;