From 84b2d4c4758e52b9509c6fe7ea317b23d1ec86d2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 21 Feb 2021 01:08:48 +0100 Subject: [PATCH] Kernel: Add "map_fixed" pledge promise This is a new promise that guards access to mmap() with MAP_FIXED. Fixed-address mappings are rarely used, but can be useful if you are trying to groom the process address space for malicious purposes. None of our programs need this at the moment, as the only user of MAP_FIXED is DynamicLoader, but the fixed mappings are constructed before the process has had a chance to pledge anything. --- Base/usr/share/man/man2/pledge.md | 1 + Kernel/Process.h | 1 + Kernel/Syscalls/mmap.cpp | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/Base/usr/share/man/man2/pledge.md b/Base/usr/share/man/man2/pledge.md index 2a20f42dc8..51b1524265 100644 --- a/Base/usr/share/man/man2/pledge.md +++ b/Base/usr/share/man/man2/pledge.md @@ -54,6 +54,7 @@ If the process later attempts to use any system functionality it has previously * `recvfd`: Receive file descriptors over a local socket * `ptrace`: The [`ptrace(2)`](ptrace.md) syscall (\*) * `prot_exec`: [`mmap(2)`](mmap.md) and [`mprotect(2)`](mprotect.md) with `PROT_EXEC` +* `map_fixed`: [`mmap(2)`](mmap.md) with `MAP_FIXED` (\*) Promises marked with an asterisk (\*) are SerenityOS specific extensions not supported by the original OpenBSD `pledge()`. diff --git a/Kernel/Process.h b/Kernel/Process.h index 01e37ac0f2..f9ee565867 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -82,6 +82,7 @@ void kgettimeofday(timeval&); __ENUMERATE_PLEDGE_PROMISE(sigaction) \ __ENUMERATE_PLEDGE_PROMISE(setkeymap) \ __ENUMERATE_PLEDGE_PROMISE(prot_exec) \ + __ENUMERATE_PLEDGE_PROMISE(map_fixed) \ __ENUMERATE_PLEDGE_PROMISE(getkeymap) enum class Pledge : u32 { diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index a18dc1d4d5..fa39188769 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -157,6 +157,10 @@ void* Process::sys$mmap(Userspace user_params) REQUIRE_PROMISE(prot_exec); } + if (prot & MAP_FIXED) { + REQUIRE_PROMISE(map_fixed); + } + if (alignment & ~PAGE_MASK) return (void*)-EINVAL;