Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2005 19:21:39 GMT
From:      Harry Coin <harrycoin@qconline.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/83687: no bounds check in kern_environment routine setenv, system crashes
Message-ID:  <200507181921.j6IJLdsj026340@www.freebsd.org>
Resent-Message-ID: <200507181930.j6IJUCr3069439@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         83687
>Category:       misc
>Synopsis:       no bounds check in kern_environment routine setenv, system crashes
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 18 19:30:12 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Harry Coin
>Release:        5.4
>Organization:
>Environment:
FreeBSD sueofficerm 5.4-RELEASE FreeBSD 5.4-RELEASE #23: Mon Jul 18 13:34:01 CDT 2005     root@server1.quietfountain.com:/usr/obj/usr/src/sys/DISKLESS  i386

>Description:
kernel kern_environment routine setenv allows dynamic additions and changes to the kernel environment (mostly hints) settings.

When setenv can't find the environment variable to set to the passed in value, it allocates a new one, gives it the passed in name, then sets it to the value.

The problem is there is no bounds checking when it is time to add a variable.  Repeated adds (which can be called from userland routine kenv) will just corrupt memory past the end of the array and eventually crash the system.

bugfix below.
>How-To-Repeat:

just use kenv to add new variables until the system dies.  Somewhere after 512 total variables.

bugfix below.
>Fix:
--- /usr/src/sys/kern/kern_environment.c	Thu Mar 10 11:09:16 2005
+++ /mnt/server1/usr/src/sys/kern/kern_environment.c	Mon Jul 18 13:57:01 2005
@@ -349,6 +349,11 @@
 		/* We add the option if it wasn't found */
 		for (i = 0; (cp = kenvp[i]) != NULL; i++)
 			;
+		if (i>=KENV_SIZE-1) {  // prevent kernel memory corruption due to runaway growth
+		  free(buf,M_KENV); 
+		  sx_xunlock(&kenv_lock);
+		  return -1;
+		}
 		kenvp[i] = buf;
 		kenvp[i + 1] = NULL;
 		sx_xunlock(&kenv_lock);

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507181921.j6IJLdsj026340>