Skip to content

fix(libkernel): block guest signals by FreeBSD's bit n - 1 - #1652

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
SleglJan:fix/libkernel-signal-mask-bit
Oct 10, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
SleglJan:fix/libkernel-signal-mask-bit

Conversation

@SleglJan

@SleglJan SleglJan commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What

Dispatch in System/src/Signals.cpp tested the blocked mask with 1u << guest, bit n. sigprocmask keeps the first word of the title's set as it is, and FreeBSD keeps signal n at bit n − 1 (_SIG_BIT), which is what FreeBSD's sigaddset (and #1641's) produces. So a title that blocked SIGTERM (bit 14) was not protected, and a set with bit 15 blocked SIGTERM instead of SIGURG.

Dispatch now tests 1u << (guest - 1). The stored mask and the set sigprocmask returns are unchanged, so they keep the title's layout. Nothing else interprets the mask's bits; sigprocmask only combines and returns it.

Found while adding the sigset functions in #1641: with them a title can build such a set without importing anything else, so the mismatch stops being latent. The two are independent changes; #1641 lists this one under Depends on so they land in order.

Tested

  • Linux (CachyOS, kernel 7.2.9, GCC 16.2.1), full build with BUILD_TESTING=ON and ANYPS5_ENABLE_SPIRV_TOOLS=ON on this branch (based on main 4b005b2): ctest --repeat until-fail:3 466/466; tools/check_conventions.py --base upstream/main passes.
  • guest_signals gains two cases: block {1u << 14} with SIG_BLOCK, raise(15) is not delivered, SIG_UNBLOCK, raise(15) is delivered; and block {1u << 15}, raise(15) is still delivered. The first was written before the change: on main it aborts (the raise is delivered through the block); it passes with the change. The existing round-trip assertions are untouched.
  • Windows: run by @hikazey on Windows 11 with the CI toolchain (comment below): guest_signals 5/5 with this change, 5/5 failures with main's Signals.cpp and the new cases, full suite 457/457. Pending delivery of a blocked signal after unblocking is not implemented here or on main; this only corrects which bit is tested.
  • Also the same Build workflow run on this commit in the fork's Actions (merged onto main 6b56175), run 37822080210: guest_signals passes its three repeats on Windows, full suite 473/473. Linux passed on a rerun after agc_driver_buffer_format hit its 120 s limit on the software Vulkan runner (the test takes 92 to 108 s on main's own runs; ci: warn about tests that take more than 30 s #1744).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

@hikazey

hikazey commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Windows run, since the description says it wasn't tested there: Windows 11 Pro (26200), MinGW-w64 GCC 15.2.0 (WinLibs r7, the CI build), Release, configured like CI, Ryzen 9 5900X. This commit merged onto main 7995d657, which merges cleanly.

build guest_signals
this PR 5/5 passed
Signals.cpp from main, new cases kept 5/5 failed
full suite with this PR 457/457 passed

So the bit n − 1 check also holds on the CRT signal/raise path that Dispatch uses on Windows: SIGTERM blocked through bit 14 isn't delivered, and bit 15 no longer blocks it.

AI-assisted: yes (Claude Code).

@SleglJan

SleglJan commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the Windows run; the description now points to it, so the CRT path is covered on both hosts.

@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
9 tasks done
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 9, 2026
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 <noreply@anthropic.com>
@SleglJan
SleglJan force-pushed the fix/libkernel-signal-mask-bit branch from 28ec8f5 to c26c1ca Compare October 9, 2026 23:33
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 9, 2026
@SleglJan

SleglJan commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto main ff8961d (head c26c1ca). #1916 (sigaction) and this PR both append cases to GuestSignals.cpp; both are kept, this PR's 12 lines after #1916's, with its two set variables renamed because term was taken. The Signals.cpp change is the same one line, and main still tests 1u << guest.

Linux (CachyOS, kernel 7.2.9, GCC 16.2.1), Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON, on this head:

AI-assisted: yes (Claude Code)

oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
oneandonlydean added a commit to oneandonlydean/AnyPS5 that referenced this pull request Oct 10, 2026
@oneandonlydean
oneandonlydean merged commit 177332d into boykopovar:main Oct 10, 2026
8 checks passed
SleglJan pushed a commit to SleglJan/AnyPS5 that referenced this pull request Oct 10, 2026
…-mask-bit

fix(libkernel): block guest signals by FreeBSD's bit n - 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants