diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 99ca217cb9..a2bbb92765 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -523,7 +523,7 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d for (auto& property : m_coredump_properties) property = {}; - auto current_thread = Thread::current(); + auto* current_thread = Thread::current(); current_thread->clear_signals(); clear_futex_queues_on_exec(); diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index d81910d46a..76ba821680 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -43,6 +43,9 @@ ErrorOr Process::sys$fork(RegisterState& regs) dbgln_if(FORK_DEBUG, "fork: child={}", child); child->address_space().set_enforces_syscall_regions(address_space().enforces_syscall_regions()); + // A child created via fork(2) inherits a copy of its parent's signal mask + child_first_thread->update_signal_mask(Thread::current()->signal_mask()); + #if ARCH(I386) auto& child_regs = child_first_thread->m_regs; child_regs.eax = 0; // fork() returns 0 in the child :^) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 5a263a1835..1219c5df3c 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -681,7 +681,7 @@ u32 Thread::signal_mask_block(sigset_t signal_set, bool block) void Thread::clear_signals() { SpinlockLocker lock(g_scheduler_lock); - m_signal_mask = 0; + // The signal mask is preserved across execve(2). m_pending_signals = 0; m_have_any_unmasked_pending_signals.store(false, AK::memory_order_release); m_signal_action_data.fill({});