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).
This commit is contained in:
Liav A 2022-12-15 20:38:19 +02:00 committed by Andrew Kaster
parent 1b5a565e55
commit 6c0486277e
8 changed files with 36 additions and 11 deletions

View file

@ -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) \

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/EnumBits.h>
#include <AK/Types.h>
namespace Kernel {
enum class VirtualMemoryRangeFlags : u32 {
None = 0,
SyscallCode = 1 << 0,
};
AK_ENUM_BITWISE_OPERATORS(VirtualMemoryRangeFlags);
}

View file

@ -320,6 +320,7 @@ public:
ErrorOr<FlatPtr> sys$pwritev(int fd, Userspace<const struct iovec*> iov, int iov_count, Userspace<off_t const*>);
ErrorOr<FlatPtr> sys$fstat(int fd, Userspace<stat*>);
ErrorOr<FlatPtr> sys$stat(Userspace<Syscall::SC_stat_params const*>);
ErrorOr<FlatPtr> sys$annotate_mapping(Userspace<void*>, int flags);
ErrorOr<FlatPtr> sys$lseek(int fd, Userspace<off_t*>, int whence);
ErrorOr<FlatPtr> sys$ftruncate(int fd, Userspace<off_t const*>);
ErrorOr<FlatPtr> sys$posix_fallocate(int fd, Userspace<off_t const*>, Userspace<off_t const*>);
@ -333,7 +334,6 @@ public:
ErrorOr<FlatPtr> sys$set_mmap_name(Userspace<Syscall::SC_set_mmap_name_params const*>);
ErrorOr<FlatPtr> sys$mprotect(Userspace<void*>, size_t, int prot);
ErrorOr<FlatPtr> sys$madvise(Userspace<void*>, size_t, int advice);
ErrorOr<FlatPtr> sys$msyscall(Userspace<void*>);
ErrorOr<FlatPtr> sys$msync(Userspace<void*>, size_t, int flags);
ErrorOr<FlatPtr> sys$purge(int mode);
ErrorOr<FlatPtr> sys$poll(Userspace<Syscall::SC_poll_params const*>);

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/API/VirtualMemoryAnnotations.h>
#include <Kernel/Arch/SafeMem.h>
#include <Kernel/Arch/SmapDisabler.h>
#include <Kernel/Arch/x86/MSR.h>
@ -561,7 +562,7 @@ ErrorOr<FlatPtr> Process::sys$allocate_tls(Userspace<char const*> initial_data,
});
}
ErrorOr<FlatPtr> Process::sys$msyscall(Userspace<void*> address)
ErrorOr<FlatPtr> Process::sys$annotate_mapping(Userspace<void*> address, int flags)
{
VERIFY_NO_PROCESS_BIG_LOCK(this);
@ -584,6 +585,8 @@ ErrorOr<FlatPtr> Process::sys$msyscall(Userspace<void*> address)
if (!region->is_mmap())
return EINVAL;
if (flags == to_underlying(VirtualMemoryRangeFlags::None))
return EINVAL;
region->set_syscall_region(true);
return 0;
});

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -16,6 +16,7 @@
#include <AK/Platform.h>
#include <AK/ScopeGuard.h>
#include <AK/Vector.h>
#include <Kernel/API/VirtualMemoryAnnotations.h>
#include <LibC/bits/pthread_integration.h>
#include <LibC/link.h>
#include <LibC/sys/mman.h>
@ -396,7 +397,7 @@ static Result<void, DlErrorMessage> 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<int>(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();
}