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>
index | next in thread | raw e-mail
>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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021128141838.7FEC41388F>
