From e7565673416a791d1039c72d07f7fbc34a5f627f Mon Sep 17 00:00:00 2001 From: "Liav A." Date: Fri, 3 May 2024 13:45:37 +0300 Subject: [PATCH] Kernel+Userland: Convert process syscall region enforce flag to SetOnce This flag is set only once, and should never reset once it has been set, making it an ideal SetOnce use-case. It also simplifies the expected conditions for the enabling prctl call, as we don't expect a boolean flag, but rather the specific prctl option will always set (enable) Process' AddressSpace syscall region enforcing. --- Kernel/Memory/AddressSpace.h | 7 ++++--- Kernel/Syscalls/fork.cpp | 3 ++- Kernel/Syscalls/prctl.cpp | 8 ++------ Userland/Libraries/LibELF/DynamicLinker.cpp | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Kernel/Memory/AddressSpace.h b/Kernel/Memory/AddressSpace.h index 5e0597025a..91004d3382 100644 --- a/Kernel/Memory/AddressSpace.h +++ b/Kernel/Memory/AddressSpace.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -48,8 +49,8 @@ public: ErrorOr> find_regions_intersecting(VirtualRange const&); - bool enforces_syscall_regions() const { return m_enforces_syscall_regions; } - void set_enforces_syscall_regions(bool b) { m_enforces_syscall_regions = b; } + bool enforces_syscall_regions() const { return m_enforces_syscall_regions.was_set(); } + void set_enforces_syscall_regions() { m_enforces_syscall_regions.set(); } void remove_all_regions(Badge); @@ -68,7 +69,7 @@ private: RegionTree m_region_tree; - bool m_enforces_syscall_regions { false }; + SetOnce m_enforces_syscall_regions; }; } diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 85a1fad4b2..e7e605cbdf 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -164,7 +164,8 @@ ErrorOr Process::sys$fork(RegisterState& regs) TRY(address_space().with([&](auto& parent_space) { return child->address_space().with([&](auto& child_space) -> ErrorOr { - child_space->set_enforces_syscall_regions(parent_space->enforces_syscall_regions()); + if (parent_space->enforces_syscall_regions()) + child_space->set_enforces_syscall_regions(); for (auto& region : parent_space->region_tree().regions()) { dbgln_if(FORK_DEBUG, "fork: cloning Region '{}' @ {}", region.name(), region.vaddr()); auto region_clone = TRY(region.try_clone()); diff --git a/Kernel/Syscalls/prctl.cpp b/Kernel/Syscalls/prctl.cpp index f783506dd9..6d6c1224e3 100644 --- a/Kernel/Syscalls/prctl.cpp +++ b/Kernel/Syscalls/prctl.cpp @@ -26,14 +26,10 @@ ErrorOr Process::sys$prctl(int option, FlatPtr arg1, FlatPtr arg2, Flat return space->enforces_syscall_regions(); }); case PR_SET_NO_NEW_SYSCALL_REGION_ANNOTATIONS: { - if (arg1 != 0 && arg1 != 1) + if (arg1 != 0) return EINVAL; - bool prohibit_new_annotated_syscall_regions = (arg1 == 1); return address_space().with([&](auto& space) -> ErrorOr { - if (space->enforces_syscall_regions() && !prohibit_new_annotated_syscall_regions) - return EPERM; - - space->set_enforces_syscall_regions(prohibit_new_annotated_syscall_regions); + space->set_enforces_syscall_regions(); return 0; }); return 0; diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index 627833e798..679a9b1401 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -739,7 +739,7 @@ Examples of static-pie ELF objects are ELF packers, and the system dynamic loade entry_point = entry_point.offset(main_executable_loader->base_address().get()); auto entry_point_function = reinterpret_cast(entry_point.as_ptr()); - int rc = syscall(SC_prctl, PR_SET_NO_NEW_SYSCALL_REGION_ANNOTATIONS, 1, 0, nullptr); + int rc = syscall(SC_prctl, PR_SET_NO_NEW_SYSCALL_REGION_ANNOTATIONS, 0, 0, nullptr); if (rc < 0) { VERIFY_NOT_REACHED(); }