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(); }