[Bug 3981] sshd can lose SIGTERM delivered during SIGHUP restart/re-exec
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Tue Sep 15 23:15:28 AEST 2026
https://bugzilla.mindrot.org/show_bug.cgi?id=3981
--- Comment #2 from dambi at tio.cz <dambi at tio.cz> ---
Thank you for looking into this. Though from taking a quick look at the
proposed patch, I do not think it will actually work, since modifying
nsigset has no effect on subsequent sigprocmask(SIG_SETMASK, &osigset,
NULL) call.
FWIW, gpt-6 have come to the same conclusion:
As pasted, the changes do not fix the race. They modify nsigset, but
this call restores the unchanged osigset, unblocking SIGTERM:
sigprocmask(SIG_SETMASK, &osigset, NULL);
SIGTERM then sets received_sigterm in the old process image, and
execv() discards that flag.
If upstream also intended this replacement, that version works:
sigdelset(&nsigset, SIGTERM);
sigdelset(&nsigset, SIGQUIT);
sigprocmask(SIG_UNBLOCK, &nsigset, NULL);
sighup_restart();
Here, removing termination signals from the set being unblocked
leaves them blocked. They remain pending across execv() and terminate
the new image when startup clears its signal mask.
I verified this with a reduced C reproducer on Solaris 11.4 using
real signals and execv(), injecting signals at three vulnerable points,
ten times each:
Version SIGTERM preserved SIGQUIT preserved
━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━
Our patch 30/30 0/30
──────────────────────────── ───────────────────
───────────────────
Changes as pasted 0/30 0/30
──────────────────────────── ───────────────────
───────────────────
With SIG_UNBLOCK, &nsigset 30/30 30/30
--
You are receiving this mail because:
You are watching someone on the CC list of the bug.
You are watching the assignee of the bug.
More information about the openssh-bugs
mailing list