summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-28 14:55:06 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-28 16:23:38 +0100
commitb6937e2560308379460a9f6d4a61bbf55e17dfde (patch)
tree5ca13691c5142131028d0753c8a982e6dcbc1ea4 /Kernel/Syscalls
parentd3de138d64e49bf04fcd1aaa5a98dff8bf230f91 (diff)
downloadserenity-b6937e2560308379460a9f6d4a61bbf55e17dfde.zip
Kernel+LibC: Add MAP_RANDOMIZED flag for sys$mmap()
This can be used to request random VM placement instead of the highly predictable regular mmap(nullptr, ...) VM allocation strategy. It will soon be used to implement ASLR in the dynamic loader. :^)
Diffstat (limited to 'Kernel/Syscalls')
-rw-r--r--Kernel/Syscalls/mmap.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp
index aa555b71f3..be1ebdf818 100644
--- a/Kernel/Syscalls/mmap.cpp
+++ b/Kernel/Syscalls/mmap.cpp
@@ -119,6 +119,7 @@ void* Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
bool map_stack = flags & MAP_STACK;
bool map_fixed = flags & MAP_FIXED;
bool map_noreserve = flags & MAP_NORESERVE;
+ bool map_randomized = flags & MAP_RANDOMIZED;
if (map_shared && map_private)
return (void*)-EINVAL;
@@ -133,16 +134,23 @@ void* Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
return (void*)-EINVAL;
Region* region = nullptr;
- auto range = allocate_range(VirtualAddress(addr), size, alignment);
- if (!range.has_value()) {
- if (addr && !map_fixed) {
- // If there's an address but MAP_FIXED wasn't specified, the address is just a hint.
- range = allocate_range({}, size, alignment);
+ Optional<Range> range;
+
+ if (map_randomized) {
+ range = page_directory().range_allocator().allocate_randomized(size, alignment);
+ } else {
+ range = allocate_range(VirtualAddress(addr), size, alignment);
+ if (!range.has_value()) {
+ if (addr && !map_fixed) {
+ // If there's an address but MAP_FIXED wasn't specified, the address is just a hint.
+ range = allocate_range({}, size, alignment);
+ }
}
- if (!range.has_value())
- return (void*)-ENOMEM;
}
+ if (!range.has_value())
+ return (void*)-ENOMEM;
+
if (map_anonymous) {
auto strategy = map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve;
auto region_or_error = allocate_region(range.value(), !name.is_null() ? name : "mmap", prot, strategy);