From 9ee2c606c1d03ecb955aa8a2624b9db4aa9752a2 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 22 Sep 2011 21:38:30 +1000 Subject: [PATCH] - djm@cvs.openbsd.org 2011/09/09 22:38:21 [sshd.c] kill the preauth privsep child on fatal errors in the monitor; ok markus@ --- ChangeLog | 4 ++++ sshd.c | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd7032735..dfce82822 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,10 @@ suppress adding '--' to remote commandlines when the first argument does not start with '-'. saves breakage on some difficult-to-upgrade embedded/router platforms; feedback & ok dtucker ok markus + - djm@cvs.openbsd.org 2011/09/09 22:38:21 + [sshd.c] + kill the preauth privsep child on fatal errors in the monitor; + ok markus@ 20110909 - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From diff --git a/sshd.c b/sshd.c index cc1039558..28a8a489b 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.385 2011/06/23 09:34:13 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.386 2011/09/09 22:38:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -239,6 +239,7 @@ int startup_pipe; /* in child */ /* variables used for privilege separation */ int use_privsep = -1; struct monitor *pmonitor = NULL; +int privsep_is_preauth = 1; /* global authentication context */ Authctxt *the_authctxt = NULL; @@ -650,10 +651,13 @@ privsep_preauth(Authctxt *authctxt) /* Wait for the child's exit status */ while (waitpid(pid, &status, 0) < 0) { - if (errno != EINTR) - fatal("%s: waitpid: %s", __func__, - strerror(errno)); + if (errno == EINTR) + continue; + pmonitor->m_pid = -1; + fatal("%s: waitpid: %s", __func__, strerror(errno)); } + privsep_is_preauth = 0; + pmonitor->m_pid = -1; if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) fatal("%s: preauth child exited with status %d", @@ -2360,8 +2364,16 @@ do_ssh2_kex(void) void cleanup_exit(int i) { - if (the_authctxt) + if (the_authctxt) { do_cleanup(the_authctxt); + if (privsep_is_preauth && pmonitor->m_pid > 1) { + debug("Killing privsep child %d", pmonitor->m_pid); + if (kill(pmonitor->m_pid, SIGKILL) != 0 && + errno == ESRCH) + error("%s: kill(%d): %s", __func__, + pmonitor->m_pid, strerror(errno)); + } + } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ if (!use_privsep || mm_is_monitor())