Bug 271 - SSHD should unblock SIGCHLD - POSIX signal blocks survive exec()
Summary: SSHD should unblock SIGCHLD - POSIX signal blocks survive exec()
Status: CLOSED WORKSFORME
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: -current
Hardware: Other Other
: P2 enhancement
Assignee: OpenSSH Bugzilla mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-06-12 00:43 AEST by Nicolas Williams
Modified: 2006-10-07 11:35 AEST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nicolas Williams 2002-06-12 00:43:10 AEST
POSIX requires that signal block masks be inherited across exec() calls.

As a result, any porgram that needs to use specific signal and which has no 
good reason to accept inheritance of blocking of such signals should explicitly 
unblock those signals.

Furthermore, login-type programs should really unblock all signals, IMO (I have 
yet to find a scenario where I'd want my login shell to inherit and keep any 
non-empty signal mask).

If sshd is started with SIGCHLD (SIGCLD) blocked then sshd ends up failing to 
notice the death of child processes, and therefore SSHv2 sessions hang on exit. 
Diagnosis is trivial on any OS that provides tools for inspecting the signal 
disposition of a process: if an sshd has at least one defunct process, sleeps 
in poll()/select() and has SIGCHLD blocked, and its SSHv2 client is hanging on 
exit, then the sshd must have been started with SIGCHLD blocked. Out of 
thousands of installations I have witnessed this behaviour on three systems.

At the very least sshd should, early on, use sigprocmask() to retrieve the 
current mask, clear SIGCHLD from the mask and set the modified mask. 
Preferably, perhaps, sshd should set an empty signal mask before exec()ing any 
program on behalf of a client.

Most shells (I've checked a few, including Bash) clear SIGCHLD from the signal 
mask, but generally don't clear all other signals from the mask.

NOTE: sigprocmask() can have its new signal mask pointer argument given as 
NULL, in which case sigprocmask() should only retrieve the current mask and 
ignore its first argument, but the compatibility shim provided by portable 
OpenSSH does not support this mode of operation. This can be fixed with a one-
liner.

NOTE: This issue is relevant to all POSIX-compatible platforms.

Thoughts?

Nico
Comment 1 Damien Miller 2003-01-07 18:13:08 AEDT
We already reset SIGCHLD to SIG_DFL in main(), maybe we don't do it early enough...
Comment 2 Damien Miller 2003-05-16 13:29:57 AEST
Could you verify this with a recent version, preferably including diag output.
Comment 3 Damien Miller 2005-02-09 15:49:08 AEDT
20 months + no reply == closed bug
Comment 4 Darren Tucker 2006-10-07 11:35:25 AEST
Change all RESOLVED bug to CLOSED with the exception of the ones fixed post-4.4.