From c26c1cae5bd5e31ec4e224dbf46b5b2fb72bef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=A0l=C3=A9gl?= Date: Thu, 8 Oct 2026 17:38:32 +0200 Subject: [PATCH] fix(libkernel): block guest signals by FreeBSD's bit n - 1 sigprocmask keeps the first word of the title's set as it is, where FreeBSD keeps signal n at bit n - 1 (_SIG_BIT), but Dispatch tested bit n. A title that blocked SIGTERM with a FreeBSD-built set (bit 14) was not protected, and a set with bit 15 blocked SIGTERM instead of SIGURG. Dispatch now tests bit n - 1; the stored mask and the set returned by sigprocmask are unchanged. Co-Authored-By: Claude Fable 5.1 --- core/libs/prx/libkernel/System/src/Signals.cpp | 2 +- core/libs/tests/GuestSignals.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libkernel/System/src/Signals.cpp b/core/libs/prx/libkernel/System/src/Signals.cpp index e6a955b74..dd7ad433c 100644 --- a/core/libs/prx/libkernel/System/src/Signals.cpp +++ b/core/libs/prx/libkernel/System/src/Signals.cpp @@ -53,7 +53,7 @@ void Dispatch(int native) { // Preserve the guest's persistent registration across CRT delivery. std::signal(native, Dispatch); #endif - if ((blockedMask.load() & (1u << guest)) != 0) return; + if ((blockedMask.load() & (1u << (guest - 1))) != 0) return; const auto callback = handlers[guest].load(); if (reinterpret_cast(callback) > 1) callback(guest); } diff --git a/core/libs/tests/GuestSignals.cpp b/core/libs/tests/GuestSignals.cpp index 8c4548a81..dc5bf1a96 100644 --- a/core/libs/tests/GuestSignals.cpp +++ b/core/libs/tests/GuestSignals.cpp @@ -105,4 +105,16 @@ int main() { Require(sigaction_nid_postfix(fixed, &defaults, ¤t) == 0 && current.handler == 0); } Require(sigaction_nid_postfix(15, nullptr, nullptr) == 0); + Require(signal_nid_postfix(15, Callback) != invalid); + GuestSignalSet termMask{{1u << 14, 0, 0, 0}}; + received = 0; + Require(sigprocmask_nid_postfix(1, &termMask, nullptr) == 0); + Require(raise_nid_postfix(15) == 0 && received == 0); + Require(sigprocmask_nid_postfix(2, &termMask, nullptr) == 0); + Require(raise_nid_postfix(15) == 0 && received == 15); + GuestSignalSet urgMask{{1u << 15, 0, 0, 0}}; + received = 0; + Require(sigprocmask_nid_postfix(1, &urgMask, nullptr) == 0); + Require(raise_nid_postfix(15) == 0 && received == 15); + Require(sigprocmask_nid_postfix(2, &urgMask, nullptr) == 0); }