Call for testing: OpenSSH-5.9

Damien Miller djm at mindrot.org
Mon Aug 29 16:30:37 EST 2011


On Mon, 29 Aug 2011, Darren Tucker wrote:

> On Mon, Aug 29, 2011 at 3:34 PM, Tim Rice <tim at multitalents.net> wrote:
> [...]
> > +#ifdef POLL_USES_FD
> > +       if (setrlimit(RLIMIT_NOFILE, &rl_one) == -1)
> > +#else
> >        if (setrlimit(RLIMIT_NOFILE, &rl_zero) == -1)
> > +#endif
> 
> Problem is this destroys a lot of the value of the rlimit sandbox,
> since a compromised slave can close all descriptors and open a single
> new one with connect() and, eg, use it to probe serves on localhost or
> beyond the machine in question.
> 
> One thing we could do to mitigate this is to have the monitoring
> SIGKILL the slave if the socketpair closes.  It's racy so there's a
> window where a compromised slave could potentially make a connection.

The below diff does this. IMO it would be better to turn the sandbox
off for the platforms that don't support it for this release.

Index: sshd.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sshd.c,v
retrieving revision 1.385
diff -u -p -r1.385 sshd.c
--- sshd.c	23 Jun 2011 09:34:13 -0000	1.385
+++ sshd.c	29 Aug 2011 06:29:32 -0000
@@ -222,6 +222,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;
@@ -637,10 +638,13 @@ privsep_preauth(Authctxt *authctxt)
 
 		/* Wait for the child's exit status */
 		while (waitpid(pid, &status, 0) < 0) {
+			pmonitor->m_pid = -1;
 			if (errno != EINTR)
 				fatal("%s: waitpid: %s", __func__,
 				    strerror(errno));
 		}
+		pmonitor->m_pid = -1;
+		privsep_is_preauth = 0;
 		if (WIFEXITED(status)) {
 			if (WEXITSTATUS(status) != 0)
 				fatal("%s: preauth child exited with status %d",
@@ -2217,7 +2221,14 @@ 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(SIGKILL, pmonitor->m_pid) != 0)
+				error("%s: kill(%d): %s", __func__,
+				    pmonitor->m_pid, strerror(errno));
+		}
+	}
 	_exit(i);
 }


More information about the openssh-unix-dev mailing list