From 8661936d7de17d645b10a781f0d2330656fe43e3 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Mon, 5 Dec 2022 16:21:26 +0100 Subject: [PATCH] base: aquire context mutex in local_submit() Some signal-heavy scenarios (e.g., libc_integration) produced the following warning that hinted a data race on signal data in the context object. Warning: returning signal with num == 0 The cause was the use of Signal_context::local_submit() in the libc introduced in 424ed1b79a4 libc: remove Reconstructible / use local_submit in kernel in combination with a missing context-mutex aquisition resulting in a data race on Signal_context::_curr_signal. Issue #3923 --- repos/base-hw/src/lib/base/signal_receiver.cc | 4 ++-- repos/base/src/lib/base/signal.cc | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/repos/base-hw/src/lib/base/signal_receiver.cc b/repos/base-hw/src/lib/base/signal_receiver.cc index 94660af344..a39bec0602 100644 --- a/repos/base-hw/src/lib/base/signal_receiver.cc +++ b/repos/base-hw/src/lib/base/signal_receiver.cc @@ -85,7 +85,7 @@ void Signal_receiver::_platform_begin_dissolve(Signal_context * const c) { Mutex::Guard context_guard(c->_mutex); c->_pending = true; - c->_curr_signal = Signal::Data(nullptr, 0); + c->_curr_signal = Signal::Data(); } Kernel::kill_signal_context(Capability_space::capid(c->_cap)); } @@ -166,7 +166,7 @@ Signal Signal_receiver::pending_signal() _contexts.head(context._next); context._pending = false; result = context._curr_signal; - context._curr_signal = Signal::Data(0, 0); + context._curr_signal = Signal::Data(); Trace::Signal_received trace_event(context, result.num); return true; diff --git a/repos/base/src/lib/base/signal.cc b/repos/base/src/lib/base/signal.cc index 03adbb1f91..2edfcb965f 100644 --- a/repos/base/src/lib/base/signal.cc +++ b/repos/base/src/lib/base/signal.cc @@ -117,6 +117,7 @@ namespace Genode { void Signal_context::local_submit() { if (_receiver) { + Mutex::Guard guard(_mutex); /* construct and locally submit signal object */ Signal::Data signal(this, 1); _receiver->local_submit(signal); @@ -261,7 +262,7 @@ Signal Signal_receiver::pending_signal() _contexts.head(context._next); context._pending = false; result = context._curr_signal; - context._curr_signal = Signal::Data(0, 0); + context._curr_signal = Signal::Data(); Trace::Signal_received trace_event(context, result.num); return true;