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
We already reset SIGCHLD to SIG_DFL in main(), maybe we don't do it early enough...
Could you verify this with a recent version, preferably including diag output.
20 months + no reply == closed bug
Change all RESOLVED bug to CLOSED with the exception of the ones fixed post-4.4.