Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Nov 2002 15:18:38 +0100 (CET)
From:      Daniel Lang <dl@leo.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/45824: malloc() overflow bug
Message-ID:  <20021128141838.7FEC41388F@atrbg11.informatik.tu-muenchen.de>

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

>Number:         45824
>Category:       bin
>Synopsis:       malloc() overflow bug
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 28 06:20:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Daniel Lang
>Release:        FreeBSD 4.7-STABLE i386
>Organization:
LEO
>Environment:
System: FreeBSD atrbg11.informatik.tu-muenchen.de 4.7-STABLE FreeBSD 4.7-STABLE #14: Mon Nov 18 08:57:20 CET 2002 root@atrbg11.informatik.tu-muenchen.de:/usr/obj/usr/src/sys/ATRBG11 i386


>Description:

  malloc() can be passed a large argument, such that the new break adress
  overflows and the segment size is actually reduced, causing the
  application to crash anywhere.


>How-To-Repeat:

example-code to crash:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>

int main(void) {
	
	struct passwd* p;

 	char *buffer1, *buffer2;
    int i;

	/* allocate say 80 MB */
	buffer1 = malloc(80*1024*1024*sizeof(char));

	if(!buffer1) {
		fprintf(stderr,"Could not even allocate buffer1\n");
		exit(-1);
	}
	
	/* now allocate so much, that we get a close overflow */
	buffer2 = malloc(-83876080);

	if(!buffer2) {
		fprintf(stderr,"malloc() of buffer2 fails as expected, no exit\n");
	}
    
	/* do something else */

	fprintf(stdout,"doing other things, but don't touch buffer2\n");

	p = getpwuid(getuid());
	fprintf(stdout,"getpwuid: Name: %s\n",p->pw_name);

    /* write something to buffer1 */
	for(i=0; i<8388608; ++i) {
        strlcpy(buffer1+i,"0123456789",11);
	}

	p = getpwuid(getuid());
	fprintf(stdout,"getpwuid: Name: %s\n",p->pw_name);

	exit(0);
}
[..]

atrbg11:~/tmp>gcc -Wall -g -o malloc_test malloc_test.c
atrbg11:~/tmp>./malloc_test 
zsh: segmentation fault (core dumped)  ./malloc_test
atrbg11:~/tmp>gdb ./malloc_test malloc_test.core 
GNU gdb 4.18 (FreeBSD)
[..]
Core was generated by `malloc_test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libc.so.4...done.
Reading symbols from /usr/libexec/ld-elf.so.1...done.
#0  0x280de255 in isatty () from /usr/lib/libc.so.4
(gdb) bt 
#0  0x280de255 in isatty () from /usr/lib/libc.so.4
#1  0x280de56d in isatty () from /usr/lib/libc.so.4
#2  0x280dec79 in malloc () from /usr/lib/libc.so.4
#3  0x8048645 in main () at malloc_test.c:24
#4  0x804855a in _start ()
(gdb) 

(unfortunately I did not have the libc.so.4 with symbols at hand).

Please note, that the program _never_ touches buffer2 and still crashes!


>Fix:

--- src/lib/libc/stdlib/malloc.c.orig	Thu Nov 28 09:51:09 2002
+++ src/lib/libc/stdlib/malloc.c	Thu Nov 28 09:53:00 2002
@@ -307,6 +307,14 @@
     result = (caddr_t)pageround((u_long)sbrk(0));
     tail = result + (pages << malloc_pageshift);
 
+	/* check for overflow */
+	if(tail < result) {
+#ifdef EXTRA_SANITY
+	wrterror("(ES): overflow in map_pages; failed\n");
+#endif /* EXTRA_SANITY */
+	return 0;
+	}
+
     if (brk(tail)) {
 #ifdef EXTRA_SANITY
 	wrterror("(ES): map_pages fails\n");

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

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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