OpenSSH Security Advisory: buffer.adv

Dries Schellekens gwyllion at ace.ulyssis.org
Thu Sep 18 02:10:10 EST 2003


On Wed, 17 Sep 2003, Markus Friedl wrote:

> This is the 2nd revision of the Advisory.
>
> This document can be found at:  http://www.openssh.com/txt/buffer.adv
>
> 1. Versions affected:
>
>         All versions of OpenSSH's sshd prior to 3.7.1 contain buffer
>         management errors.  It is uncertain whether these errors are
>         potentially exploitable, however, we prefer to see bugs
>         fixed proactively.
>
>         Other implementations sharing common origin may also have
>         these issues.
>
> 2. Solution:
>
> 	Upgrade to OpenSSH 3.7.1 or apply the following patch.
>
> ===================================================================
> Appendix A: patch for OpenSSH 3.6.1 and earlier

[snip]

> ===================================================================
> Appendix B: patch for OpenSSH 3.7

[snip]

Will the 4 extra fixes by Solar Designer be included as well?

>From the Owl Changelog
2003/09/17	Package: openssh
SECURITY FIX	Severity: medium, remote, active

Multiple memory management errors have been discovered in OpenSSH, and
this update corrects 6 such real or potential errors based on an
exhaustive review of the OpenSSH source code for uses of *realloc()
functions. At this time, it is uncertain whether and which of these bugs
are exploitable. If exploits are possible, due to privilege separation,
the worst direct impact should be limited to arbitrary code execution
under the sshd pseudo-user account restricted within the chroot jail
/var/empty, or under the logged in user account. Reference:
http://www.openssh.com/txt/buffer.adv


openssh-3.6.1p2-owl-realloc.diff looks like this

diff -urp openssh-3.6.1p2.orig/deattack.c openssh-3.6.1p2/deattack.c
--- openssh-3.6.1p2.orig/deattack.c	Tue Mar  5 01:53:05 2002
+++ openssh-3.6.1p2/deattack.c	Wed Sep 17 00:18:30 2003
@@ -100,12 +100,12 @@ detect_attack(u_char *buf, u_int32_t len

 	if (h == NULL) {
 		debug("Installing crc compensation attack detector.");
+		h = (u_int16_t *) xmalloc(l * HASH_ENTRYSIZE);
 		n = l;
-		h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE);
 	} else {
 		if (l > n) {
+			h = (u_int16_t *) xrealloc(h, l * HASH_ENTRYSIZE);
 			n = l;
-			h = (u_int16_t *) xrealloc(h, n * HASH_ENTRYSIZE);
 		}
 	}

diff -urp openssh-3.6.1p2.orig/misc.c openssh-3.6.1p2/misc.c
--- openssh-3.6.1p2.orig/misc.c	Mon Dec 23 02:44:36 2002
+++ openssh-3.6.1p2/misc.c	Wed Sep 17 00:50:27 2003
@@ -308,18 +308,21 @@ addargs(arglist *args, char *fmt, ...)
 {
 	va_list ap;
 	char buf[1024];
+	int nalloc;

 	va_start(ap, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, ap);
 	va_end(ap);

+	nalloc = args->nalloc;
 	if (args->list == NULL) {
-		args->nalloc = 32;
+		nalloc = 32;
 		args->num = 0;
-	} else if (args->num+2 >= args->nalloc)
-		args->nalloc *= 2;
+	} else if (args->num+2 >= nalloc)
+		nalloc *= 2;

-	args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
+	args->list = xrealloc(args->list, nalloc * sizeof(char *));
+	args->nalloc = nalloc;
 	args->list[args->num++] = xstrdup(buf);
 	args->list[args->num] = NULL;
 }
diff -urp openssh-3.6.1p2.orig/session.c openssh-3.6.1p2/session.c
--- openssh-3.6.1p2.orig/session.c	Fri Mar 21 01:18:09 2003
+++ openssh-3.6.1p2/session.c	Wed Sep 17 00:34:35 2003
@@ -844,8 +844,9 @@ static void
 child_set_env(char ***envp, u_int *envsizep, const char *name,
 	const char *value)
 {
-	u_int i, namelen;
 	char **env;
+	u_int envsize;
+	u_int i, namelen;

 	/*
 	 * Find the slot where the value should be stored.  If the variable
@@ -862,12 +863,13 @@ child_set_env(char ***envp, u_int *envsi
 		xfree(env[i]);
 	} else {
 		/* New variable.  Expand if necessary. */
-		if (i >= (*envsizep) - 1) {
-			if (*envsizep >= 1000)
-				fatal("child_set_env: too many env vars,"
-				    " skipping: %.100s", name);
-			(*envsizep) += 50;
-			env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
+		envsize = *envsizep;
+		if (i >= envsize - 1) {
+			if (envsize >= 1000)
+				fatal("child_set_env: too many env vars");
+			envsize += 50;
+			env = (*envp) = xrealloc(env, envsize * sizeof(char *));
+			*envsizep = envsize;
 		}
 		/* Need to set the NULL pointer at end of array beyond the new slot. */
 		env[i + 1] = NULL;
diff -urp openssh-3.6.1p2.orig/ssh-agent.c openssh-3.6.1p2/ssh-agent.c
--- openssh-3.6.1p2.orig/ssh-agent.c	Sat Mar 15 00:37:09 2003
+++ openssh-3.6.1p2/ssh-agent.c	Wed Sep 17 00:42:15 2003
@@ -767,7 +767,7 @@ process_message(SocketEntry *e)
 static void
 new_socket(sock_type type, int fd)
 {
-	u_int i, old_alloc;
+	u_int i, old_alloc, new_alloc;

 	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
 		error("fcntl O_NONBLOCK: %s", strerror(errno));
@@ -778,25 +778,26 @@ new_socket(sock_type type, int fd)
 	for (i = 0; i < sockets_alloc; i++)
 		if (sockets[i].type == AUTH_UNUSED) {
 			sockets[i].fd = fd;
-			sockets[i].type = type;
 			buffer_init(&sockets[i].input);
 			buffer_init(&sockets[i].output);
 			buffer_init(&sockets[i].request);
+			sockets[i].type = type;
 			return;
 		}
 	old_alloc = sockets_alloc;
-	sockets_alloc += 10;
+	new_alloc = sockets_alloc + 10;
 	if (sockets)
-		sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0]));
+		sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0]));
 	else
-		sockets = xmalloc(sockets_alloc * sizeof(sockets[0]));
-	for (i = old_alloc; i < sockets_alloc; i++)
+		sockets = xmalloc(new_alloc * sizeof(sockets[0]));
+	for (i = old_alloc; i < new_alloc; i++)
 		sockets[i].type = AUTH_UNUSED;
-	sockets[old_alloc].type = type;
+	sockets_alloc = new_alloc;
 	sockets[old_alloc].fd = fd;
 	buffer_init(&sockets[old_alloc].input);
 	buffer_init(&sockets[old_alloc].output);
 	buffer_init(&sockets[old_alloc].request);
+	sockets[old_alloc].type = type;
 }

 static int



Cheers,

Dries
--
Dries Schellekens
email: gwyllion at ulyssis.org




More information about the openssh-unix-dev mailing list