[Bug 1905] New: check_parent_exists() logic does not cover all cases

bugzilla-daemon at bugzilla.mindrot.org bugzilla-daemon at bugzilla.mindrot.org
Fri May 13 05:32:09 EST 2011


https://bugzilla.mindrot.org/show_bug.cgi?id=1905

           Summary: check_parent_exists() logic does not cover all cases
           Product: Portable OpenSSH
           Version: 5.8p2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ssh-agent
        AssignedTo: unassigned-bugs at mindrot.org
        ReportedBy: dkg at fifthhorseman.net


As initially reported on the mailing list:

http://lists.mindrot.org/pipermail/openssh-unix-dev/2006-April/024144.html

Alan P. Barrett wrote:

The check_parent_exists() function in ssh-agent.c does this:

        if (parent_pid != -1 && kill(parent_pid, 0) < 0)

however, the kill can fail with EPERM even if the parent_pid
exists.  For example, consider this command:

        ssh-agent sh -c 'ssh-add ; exec sudo sh -i'

The original ssh-agent process sets things up so that the "sh -c '...'"
process is the parent of a child ssh-agent process; then the "sh -c
'...' process execs sudo (which is setuid root), and sudo execs "sh -i"
(which is now running as root); so now the "sh -i" process (running as
root) is the parent of the "ssh-agent" process (running as the original
user).  When the ssh-agent child process calls check_parent_exists()
after 10 seconds, the kill will fail with EPERM, and the ssh-agent
process will exit.  The obvious symptom is that "ssh-add -l" executed
in the child shell works if you are quick enough, but doesn't work 10
seconds later.

Two potential fixes come to mind:

A: if (parent_pid != -1 && kill(parent_pid, 0) < 0 && errno == ESRCH)

B: if (parent_pid != -1 && getppid() != parent_pid)

Fix A assumes that errno == ESRCH means that the process really doesn't
exist, and that other errno values mean other things.  This assumption
would fail in a unix-like OS that, for security reasons, decides not to
let processes learn anything about the existence of processes owned by
other users.

Fix B assumes that, when your parent exits, you get re-parented to pid
1
and the result from getppid() changes.  I have tested this and it works
for me.  I append a patch.

-- 
Configure bugmail: https://bugzilla.mindrot.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching the assignee of the bug.


More information about the openssh-bugs mailing list