summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls/fork.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-08-21 12:18:26 +0200
committerAndreas Kling <kling@serenityos.org>2022-08-21 12:25:14 +0200
commit8ed06ad814734430193f3673b5e00861eda9aa47 (patch)
tree1a21a6c5ba65c1de3e9446eb091ec82b922f3780 /Kernel/Syscalls/fork.cpp
parent728c3fbd14252bd746f97dbb5441063992074b6b (diff)
downloadserenity-8ed06ad814734430193f3673b5e00861eda9aa47.zip
Kernel: Guard Process "protected data" with a spinlock
This ensures that both mutable and immutable access to the protected data of a process is serialized. Note that there may still be multiple TOCTOU issues around this, as we have a bunch of convenience accessors that make it easy to introduce them. We'll need to audit those as well.
Diffstat (limited to 'Kernel/Syscalls/fork.cpp')
-rw-r--r--Kernel/Syscalls/fork.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp
index 2009f743a7..a0e209fa4a 100644
--- a/Kernel/Syscalls/fork.cpp
+++ b/Kernel/Syscalls/fork.cpp
@@ -49,18 +49,19 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
child->m_pg = m_pg;
- {
- ProtectedDataMutationScope scope { *child };
- child->m_protected_values.promises = m_protected_values.promises.load();
- child->m_protected_values.execpromises = m_protected_values.execpromises.load();
- child->m_protected_values.has_promises = m_protected_values.has_promises.load();
- child->m_protected_values.has_execpromises = m_protected_values.has_execpromises.load();
- child->m_protected_values.sid = m_protected_values.sid;
- child->m_protected_values.credentials = m_protected_values.credentials;
- child->m_protected_values.umask = m_protected_values.umask;
- child->m_protected_values.signal_trampoline = m_protected_values.signal_trampoline;
- child->m_protected_values.dumpable = m_protected_values.dumpable;
- }
+ with_protected_data([&](auto& my_protected_data) {
+ child->with_mutable_protected_data([&](auto& child_protected_data) {
+ child_protected_data.promises = my_protected_data.promises.load();
+ child_protected_data.execpromises = my_protected_data.execpromises.load();
+ child_protected_data.has_promises = my_protected_data.has_promises.load();
+ child_protected_data.has_execpromises = my_protected_data.has_execpromises.load();
+ child_protected_data.sid = my_protected_data.sid;
+ child_protected_data.credentials = my_protected_data.credentials;
+ child_protected_data.umask = my_protected_data.umask;
+ child_protected_data.signal_trampoline = my_protected_data.signal_trampoline;
+ child_protected_data.dumpable = my_protected_data.dumpable;
+ });
+ });
dbgln_if(FORK_DEBUG, "fork: child={}", child);
child->address_space().set_enforces_syscall_regions(address_space().enforces_syscall_regions());