[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