From 6c0486277e9bc8238ae82ee857a70014c9397db9 Mon Sep 17 00:00:00 2001 From: Liav A Date: Thu, 15 Dec 2022 20:38:19 +0200 Subject: [PATCH] Kernel: Reintroduce the msyscall syscall as the annotate_mapping syscall This syscall will be used later on to ensure we can declare virtual memory mappings as immutable (which means that the underlying Region is basically immutable for both future annotations or changing the protection bits of it). --- Kernel/API/Syscall.h | 2 +- Kernel/API/VirtualMemoryAnnotations.h | 21 +++++++++++++++++++ Kernel/Process.h | 2 +- Kernel/Syscalls/mmap.cpp | 5 ++++- Tests/Kernel/crash.cpp | 4 ++-- .../DevTools/UserspaceEmulator/Emulator.h | 2 +- .../UserspaceEmulator/Emulator_syscalls.cpp | 6 +++--- Userland/Libraries/LibELF/DynamicLinker.cpp | 5 +++-- 8 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 Kernel/API/VirtualMemoryAnnotations.h diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index a1c0f11da4..9109e83277 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -45,6 +45,7 @@ enum class NeedsBigProcessLock { S(alarm, NeedsBigProcessLock::Yes) \ S(allocate_tls, NeedsBigProcessLock::Yes) \ S(anon_create, NeedsBigProcessLock::No) \ + S(annotate_mapping, NeedsBigProcessLock::No) \ S(beep, NeedsBigProcessLock::No) \ S(bind, NeedsBigProcessLock::No) \ S(chdir, NeedsBigProcessLock::No) \ @@ -124,7 +125,6 @@ enum class NeedsBigProcessLock { S(mprotect, NeedsBigProcessLock::Yes) \ S(mremap, NeedsBigProcessLock::Yes) \ S(msync, NeedsBigProcessLock::Yes) \ - S(msyscall, NeedsBigProcessLock::No) \ S(munmap, NeedsBigProcessLock::Yes) \ S(open, NeedsBigProcessLock::Yes) \ S(perf_event, NeedsBigProcessLock::Yes) \ diff --git a/Kernel/API/VirtualMemoryAnnotations.h b/Kernel/API/VirtualMemoryAnnotations.h new file mode 100644 index 0000000000..ec140bd927 --- /dev/null +++ b/Kernel/API/VirtualMemoryAnnotations.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Kernel { + +enum class VirtualMemoryRangeFlags : u32 { + None = 0, + SyscallCode = 1 << 0, +}; + +AK_ENUM_BITWISE_OPERATORS(VirtualMemoryRangeFlags); + +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 9de6a3f26e..bf9d2d0c0c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -320,6 +320,7 @@ public: ErrorOr sys$pwritev(int fd, Userspace iov, int iov_count, Userspace); ErrorOr sys$fstat(int fd, Userspace); ErrorOr sys$stat(Userspace); + ErrorOr sys$annotate_mapping(Userspace, int flags); ErrorOr sys$lseek(int fd, Userspace, int whence); ErrorOr sys$ftruncate(int fd, Userspace); ErrorOr sys$posix_fallocate(int fd, Userspace, Userspace); @@ -333,7 +334,6 @@ public: ErrorOr sys$set_mmap_name(Userspace); ErrorOr sys$mprotect(Userspace, size_t, int prot); ErrorOr sys$madvise(Userspace, size_t, int advice); - ErrorOr sys$msyscall(Userspace); ErrorOr sys$msync(Userspace, size_t, int flags); ErrorOr sys$purge(int mode); ErrorOr sys$poll(Userspace); diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index f31363f893..87a7b32bce 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -561,7 +562,7 @@ ErrorOr Process::sys$allocate_tls(Userspace initial_data, }); } -ErrorOr Process::sys$msyscall(Userspace address) +ErrorOr Process::sys$annotate_mapping(Userspace address, int flags) { VERIFY_NO_PROCESS_BIG_LOCK(this); @@ -584,6 +585,8 @@ ErrorOr Process::sys$msyscall(Userspace address) if (!region->is_mmap()) return EINVAL; + if (flags == to_underlying(VirtualMemoryRangeFlags::None)) + return EINVAL; region->set_syscall_region(true); return 0; }); diff --git a/Tests/Kernel/crash.cpp b/Tests/Kernel/crash.cpp index 6f8864626e..737fae8865 100644 --- a/Tests/Kernel/crash.cpp +++ b/Tests/Kernel/crash.cpp @@ -71,7 +71,7 @@ int main(int argc, char** argv) args_parser.add_option(do_invalid_stack_pointer_on_syscall, "Make a syscall while using an invalid stack pointer", nullptr, 'T'); args_parser.add_option(do_invalid_stack_pointer_on_page_fault, "Trigger a page fault while using an invalid stack pointer", nullptr, 't'); args_parser.add_option(do_syscall_from_writeable_memory, "Make a syscall from writeable memory", nullptr, 'S'); - args_parser.add_option(do_legitimate_syscall, "Make a syscall from legitimate memory (but outside msyscall)", nullptr, 'y'); + args_parser.add_option(do_legitimate_syscall, "Make a syscall from legitimate memory (but outside syscall-code mapped region)", nullptr, 'y'); args_parser.add_option(do_execute_non_executable_memory, "Attempt to execute non-executable memory (not mapped with PROT_EXEC)", nullptr, 'X'); args_parser.add_option(do_trigger_user_mode_instruction_prevention, "Attempt to trigger an x86 User Mode Instruction Prevention fault. WARNING: This test runs only when invoked manually, see #10042.", nullptr, 'U'); #if ARCH(I386) || ARCH(X86_64) @@ -262,7 +262,7 @@ int main(int argc, char** argv) } if (do_legitimate_syscall || do_all_crash_types) { - any_failures |= !Crash("Regular syscall from outside msyscall", []() { + any_failures |= !Crash("Regular syscall from outside syscall-code mapped region", []() { // Since 'crash' is dynamically linked, and DynamicLoader only allows LibSystem to make syscalls, this should kill us: Syscall::invoke(Syscall::SC_getuid); return Crash::Failure::DidNotCrash; diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.h b/Userland/DevTools/UserspaceEmulator/Emulator.h index 5139c8ad07..3ba4225ec2 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.h +++ b/Userland/DevTools/UserspaceEmulator/Emulator.h @@ -204,7 +204,7 @@ private: u32 virt$mount(u32); u32 virt$mprotect(FlatPtr, size_t, int); FlatPtr virt$mremap(FlatPtr); - int virt$msyscall(FlatPtr); + int virt$annotate_mapping(FlatPtr); u32 virt$munmap(FlatPtr address, size_t size); u32 virt$open(u32); FlatPtr virt$perf_event(int type, FlatPtr arg1, FlatPtr arg2); diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index 92454f0965..f4dbe20730 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -46,6 +46,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$allocate_tls(arg1, arg2); case SC_anon_create: return virt$anon_create(arg1, arg2); + case SC_annotate_mapping: + return virt$annotate_mapping(arg1); case SC_beep: return virt$beep(); case SC_bind: @@ -165,8 +167,6 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$mprotect(arg1, arg2, arg3); case SC_mremap: return virt$mremap(arg1); - case SC_msyscall: - return virt$msyscall(arg1); case SC_munmap: return virt$munmap(arg1, arg2); case SC_open: @@ -1635,7 +1635,7 @@ u32 Emulator::virt$sysconf(u32 name) return syscall(SC_sysconf, name); } -int Emulator::virt$msyscall(FlatPtr) +int Emulator::virt$annotate_mapping(FlatPtr) { // FIXME: Implement this. return 0; diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index 6b2e575ce5..141d283254 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -396,7 +397,7 @@ static Result link_main_library(DeprecatedString const& pa if (loader.filepath().ends_with("/libsystem.so"sv)) { VERIFY(!loader.text_segments().is_empty()); for (auto const& segment : loader.text_segments()) { - if (syscall(SC_msyscall, segment.address().get())) { + if (syscall(SC_annotate_mapping, segment.address().get(), static_cast(VirtualMemoryRangeFlags::SyscallCode))) { VERIFY_NOT_REACHED(); } } @@ -660,7 +661,7 @@ void ELF::DynamicLinker::linker_main(DeprecatedString&& main_program_path, int m s_loaders.clear(); - int rc = syscall(SC_msyscall, nullptr); + int rc = syscall(SC_annotate_mapping, nullptr); if (rc < 0) { VERIFY_NOT_REACHED(); }