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>