Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jun 2006 20:56:30 GMT
From:      "Eugene M. Kim" <freebsd.org@ab.ote.we.lv>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/99217: pam_ssh(8) waits for a wrong ssh-agent PID at a wrong time; leaves a zombie
Message-ID:  <200606202056.k5KKuUuo010804@www.freebsd.org>
Resent-Message-ID: <200606202100.k5KL0ii4097762@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         99217
>Category:       bin
>Synopsis:       pam_ssh(8) waits for a wrong ssh-agent PID at a wrong time; leaves a zombie
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 20 21:00:44 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Eugene M. Kim
>Release:        7-current
>Organization:
>Environment:
FreeBSD seerajeane.astralblue.net 7.0-CURRENT FreeBSD 7.0-CURRENT #4: Sat Jun 17 13:46:23 PDT 2006     ab@seerajeane.astralblue.net:/home/FreeBSD/build/MAIN/obj/home/FreeBSD/build/MAIN/src/sys/PL-SEERAJEANE  i386
>Description:
When used as a session handler, pam_ssh(8) runs ssh-agent(1) with -s
flag upon session initialization, and reads various SSH_* environment
variable assignments from the agent's output.  Then, upon session close,
it kills the ssh-agent that it started earlier, then waitpid(2)-s for
the child (ssh-agent) process.

Problem #1: The ssh-agent child process that pam_ssh fork-execs exits
immediately after forking itself a new daemon process and printing out
SSH_* varaibles (SSH_AGENT_PID is the PID of this ssh-agent daemon
process, not the child process pam_ssh forked).  pam_ssh does not reap
this child in pam_ssh_start_agent(); the child becomes and remains as a
zombie until the pam_ssh host process exits and PID 1 adopts and reaps
the zombie.

Problem #2: pam_ssh incorrectly waitpid(SSH_AGENT_PID)-s upon session
close, which never succeeds because SSH_AGENT_PID is not for the child
process pam_ssh had forked earlier but for the ssh-agent daemon process
whose parent is PID 1.  It is sufficient just to kill SSH_AGENT_PID at
this point.

Problem #3: The session user may elect to kill $SSH_AGENT_PID when
he/she does not need the agent.  This causes kill(SSH_AGENT_PID) to
return ESRCH ("process not found") upon session close, which should be
handled gracefully.
>How-To-Repeat:
Enable pam_ssh in /etc/pam.d/login; login as an ordinary user at one of
the vtys; run "ps axl | grep defunct".
>Fix:
Apply the following patch from /usr:

-------------------------------- snip --------------------------------
--- src/lib/libpam/modules/pam_ssh/pam_ssh.c	Mon Sep 26 13:33:53 2005
+++ src/lib/libpam/modules/pam_ssh/pam_ssh.c.new	Tue May 16 00:04:25 2006
@@ -256,6 +256,7 @@
 pam_ssh_start_agent(pam_handle_t *pamh)
 {
 	int agent_pipe[2];
+	int status;
 	pid_t pid;
 	FILE *f;
 
@@ -294,6 +295,8 @@
 		return (PAM_SYSTEM_ERR);
 	pam_ssh_process_agent_output(pamh, f);
 	fclose(f);
+	if (waitpid(pid, &status, 0) == -1 && errno != ECHILD)
+		return (PAM_SYSTEM_ERR);
 
 	return (PAM_SUCCESS);
 }
@@ -402,7 +405,6 @@
 {
 	const char *ssh_agent_pid;
 	char *end;
-	int status;
 	pid_t pid;
 
 	if ((ssh_agent_pid = pam_getenv(pamh, "SSH_AGENT_PID")) == NULL) {
@@ -415,8 +417,7 @@
 		return (PAM_SESSION_ERR);
 	}
 	openpam_log(PAM_LOG_DEBUG, "killing ssh agent %d", (int)pid);
-	if (kill(pid, SIGTERM) == -1 ||
-	    (waitpid(pid, &status, 0) == -1 && errno != ECHILD))
+	if (kill(pid, SIGTERM) == -1 && errno != ESRCH)
 		return (PAM_SYSTEM_ERR);
 	return (PAM_SUCCESS);
 }
-------------------------------- snip --------------------------------
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606202056.k5KKuUuo010804>