Repository navigation
Guard sentinel signal dispositions before SA_SIGINFO - #16
Conversation
Handle SIG_DFL and SIG_IGN before inspecting the sigaction callback union. Preserve the original terminating signal, real handler arguments, and the VM self-predecessor fallback. Add subprocess regressions that round-trip the sentinel actions through sigaction.
| } else if (prev_action->sa_handler == SIG_IGN) { | ||
| // Ignore the signal even when SA_SIGINFO is set on the saved disposition. |
There was a problem hiding this comment.
Returning is right for a signal sent with kill(), but for a real fault the faulting instruction re-executes, so the process spins instead of dying. With SIGSEGV ignored and the VM handler installed, a null write in host code never terminates; without the VM handler the kernel kills it despite SIG_IGN. Master already does this without SA_SIGINFO; this extends it to the SA_SIGINFO case, which used to crash. The OC adapter in wire-sysio#757 terminates for an ignored predecessor. Could this take the default branch when fault_is_synchronous(sig, info) (it would need the SIGFPE codes)? Not blocking.
| sigaction(chained_signal, &action, nullptr) != 0 || | ||
| sigaction(chained_signal, nullptr, &sysio::vm::prev_signal_handler<chained_signal>) != 0) | ||
| _exit(child_setup_failure); | ||
| std::signal(chained_signal, SIG_DFL); |
There was a problem hiding this comment.
Resetting SIGILL to SIG_DFL here hides the restore in the default branch: with the sigaction(sig, prev_action, nullptr) line removed the suite still passes, although in production raise would then recurse through the VM handler. Installing signal_handler as the current disposition instead keeps all four cases passing and fails the default case without the restore.
A previous signal action can carry
SA_SIGINFOtogether withSIG_IGNorSIG_DFL.chain_previous_signal_handlercurrently decodessa_sigactionfirst and calls the sentinel as an address, crashing an ignored action or terminating a default action with the wrong signal.Check the default and ignored dispositions before interpreting the callback union. Ignored signals return; default actions restore the saved disposition and re-raise the original signal. Legacy and three-argument callbacks retain their existing arguments, and a previous VM handler still uses the recursion fallback.
Regression tests round-trip default and ignored actions through the kernel with either flag setting, isolate termination in child processes, verify callback argument forwarding, and cover the VM self-predecessor guard. The new tests fail against the original header in both sentinel cases.
Validation on Linux x86-64:
Sysio consumers need a registry port revision after this change is merged; this PR does not update the registry.