mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibCore: Fix signal handler deadlock in EventLoopImplementationUnix
handle_signal() called ThreadData::the() which can acquire a write lock on s_thread_data_lock if the thread hasn't initialized its ThreadData yet. If the signal interrupts a thread that already holds a read lock on s_thread_data_lock (e.g. in unregister_notifier()), this deadlocks — the write lock waits for the read lock, but the read lock holder is blocked in the signal handler. Fix by accessing the thread-local s_this_thread_data directly. If the thread has no ThreadData, there's no wake pipe to write to, so we just return.
This commit is contained in:
committed by
Andreas Kling
parent
656a84e180
commit
643f2884cc
Notes:
github-actions[bot]
2026-03-07 12:10:59 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/643f2884cc8 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8304
@@ -565,7 +565,14 @@ bool SignalHandlers::remove(int handler_id)
|
||||
void EventLoopManagerUnix::handle_signal(int signal_number)
|
||||
{
|
||||
VERIFY(signal_number != 0);
|
||||
auto& thread_data = ThreadData::the();
|
||||
|
||||
// Use the thread-local directly instead of ThreadData::the() to avoid
|
||||
// taking a write lock on s_thread_data_lock. Signal handlers must not
|
||||
// acquire locks, as we may already be holding one on this thread.
|
||||
if (!s_this_thread_data)
|
||||
return;
|
||||
auto& thread_data = *s_this_thread_data;
|
||||
|
||||
// We MUST check if the current pid still matches, because there
|
||||
// is a window between fork() and exec() where a signal delivered
|
||||
// to our fork could be inadvertently routed to the parent process!
|
||||
|
||||
Reference in New Issue
Block a user