Bug#248125: sshd processes hanging around after Ctrl-C-ed authentication
Colin Watson wrote:
I'm afraid I'm currently on 3.8.1p1 and can still reproduce it.
Damn, you're right.
It appears that what is happening is that the client exits, breaking the
TCP connection. When that happens, the privsep slave exits too, which
causes a SIGCHLD to be delivered to the monitor. The monitor then
attempts to waitpid() on the PAM "thread" which is still alive and
blissfully unaware of a problem (because nobody told it to die). That
waitpid hangs the monitor's cleanup.
The attached patch tests adds a test for this case to the signal handler
to shoot the PAM thread itself if it has to. It needs a bit more
thought, but works for me in limited testing.
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
Index: auth-pam.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
retrieving revision 1.101
diff -u -p -r1.101 auth-pam.c
--- auth-pam.c 13 May 2004 07:29:35 -0000 1.101
+++ auth-pam.c 20 May 2004 16:34:11 -0000
@@ -95,8 +95,14 @@ sshpam_sigchld_handler(int sig)
{
if (cleanup_ctxt == NULL)
return; /* handler called after PAM cleanup, shouldn't happen */
- if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1)
- return; /* couldn't wait for process */
+ if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG)
+ == -1) {
+ /* PAM thread has not exitted, privsep slave must have */
+ kill(cleanup_ctxt->pam_thread, SIGTERM);
+ if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0)
+ == -1)
+ return; /* could not wait */
+ }
if (WIFSIGNALED(sshpam_thread_status) &&
WTERMSIG(sshpam_thread_status) == SIGTERM)
return; /* terminated by pthread_cancel */
Reply to: