diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 22 |
1 files changed, 17 insertions, 5 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.385 2011/06/23 09:34:13 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.386 2011/09/09 22:38:21 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -239,6 +239,7 @@ int startup_pipe; /* in child */ | |||
239 | /* variables used for privilege separation */ | 239 | /* variables used for privilege separation */ |
240 | int use_privsep = -1; | 240 | int use_privsep = -1; |
241 | struct monitor *pmonitor = NULL; | 241 | struct monitor *pmonitor = NULL; |
242 | int privsep_is_preauth = 1; | ||
242 | 243 | ||
243 | /* global authentication context */ | 244 | /* global authentication context */ |
244 | Authctxt *the_authctxt = NULL; | 245 | Authctxt *the_authctxt = NULL; |
@@ -650,10 +651,13 @@ privsep_preauth(Authctxt *authctxt) | |||
650 | 651 | ||
651 | /* Wait for the child's exit status */ | 652 | /* Wait for the child's exit status */ |
652 | while (waitpid(pid, &status, 0) < 0) { | 653 | while (waitpid(pid, &status, 0) < 0) { |
653 | if (errno != EINTR) | 654 | if (errno == EINTR) |
654 | fatal("%s: waitpid: %s", __func__, | 655 | continue; |
655 | strerror(errno)); | 656 | pmonitor->m_pid = -1; |
657 | fatal("%s: waitpid: %s", __func__, strerror(errno)); | ||
656 | } | 658 | } |
659 | privsep_is_preauth = 0; | ||
660 | pmonitor->m_pid = -1; | ||
657 | if (WIFEXITED(status)) { | 661 | if (WIFEXITED(status)) { |
658 | if (WEXITSTATUS(status) != 0) | 662 | if (WEXITSTATUS(status) != 0) |
659 | fatal("%s: preauth child exited with status %d", | 663 | fatal("%s: preauth child exited with status %d", |
@@ -2360,8 +2364,16 @@ do_ssh2_kex(void) | |||
2360 | void | 2364 | void |
2361 | cleanup_exit(int i) | 2365 | cleanup_exit(int i) |
2362 | { | 2366 | { |
2363 | if (the_authctxt) | 2367 | if (the_authctxt) { |
2364 | do_cleanup(the_authctxt); | 2368 | do_cleanup(the_authctxt); |
2369 | if (privsep_is_preauth && pmonitor->m_pid > 1) { | ||
2370 | debug("Killing privsep child %d", pmonitor->m_pid); | ||
2371 | if (kill(pmonitor->m_pid, SIGKILL) != 0 && | ||
2372 | errno == ESRCH) | ||
2373 | error("%s: kill(%d): %s", __func__, | ||
2374 | pmonitor->m_pid, strerror(errno)); | ||
2375 | } | ||
2376 | } | ||
2365 | #ifdef SSH_AUDIT_EVENTS | 2377 | #ifdef SSH_AUDIT_EVENTS |
2366 | /* done after do_cleanup so it can cancel the PAM auth 'thread' */ | 2378 | /* done after do_cleanup so it can cancel the PAM auth 'thread' */ |
2367 | if (!use_privsep || mm_is_monitor()) | 2379 | if (!use_privsep || mm_is_monitor()) |