- (dtucker) [auth-pam.c] Have monitor die if PAM authentication thread exits
unexpectedly. with & ok djm@
diff --git a/ChangeLog b/ChangeLog
index 11329d8..95c575f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+20040114
+ - (dtucker) [auth-pam.c] Have monitor die if PAM authentication thread exits
+ unexpectedly. with & ok djm@
+
20040113
- (dtucker) [auth-pam.c] Relocate struct pam_ctxt and prototypes. No
functional changes.
@@ -1659,4 +1663,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
-$Id: ChangeLog,v 1.3166 2004/01/13 11:35:58 dtucker Exp $
+$Id: ChangeLog,v 1.3167 2004/01/14 11:14:04 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index fe2ae77..14d0c7b 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.89 2004/01/13 11:35:59 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.90 2004/01/14 11:14:05 dtucker Exp $");
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -86,6 +86,23 @@
* Simulate threads with processes.
*/
+static int sshpam_thread_status = -1;
+static mysig_t sshpam_oldsig;
+
+static void
+sshpam_sigchld_handler(int sig)
+{
+ if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1)
+ return; /* couldn't wait for process */
+ if (WIFSIGNALED(sshpam_thread_status) &&
+ WTERMSIG(sshpam_thread_status) == SIGTERM)
+ return; /* terminated by pthread_cancel */
+ if (!WIFEXITED(sshpam_thread_status))
+ fatal("PAM: authentication thread exited unexpectedly");
+ if (WEXITSTATUS(sshpam_thread_status) != 0)
+ fatal("PAM: authentication thread exited uncleanly");
+}
+
static void
pthread_exit(void *value __unused)
{
@@ -107,6 +124,7 @@
_exit(1);
default:
*thread = pid;
+ sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
return (0);
}
}
@@ -122,6 +140,9 @@
{
int status;
+ if (sshpam_thread_status != -1)
+ return (sshpam_thread_status);
+ signal(SIGCHLD, sshpam_oldsig);
waitpid(thread, &status, 0);
return (status);
}