Date: Wed, 25 Sep 2002 06:32:19 -0700 From: David Schultz <dschultz@uclink.Berkeley.EDU> To: stable@FreeBSD.ORG Subject: [v]asprintf leaks memory Message-ID: <20020925133219.GA59210@HAL9000.homeunix.com>
next in thread | raw e-mail | index | archive | help
Under certain failure conditions, [v]asprintf(3) fails to free the memory it allocates. One way (and not the only one) to reproduce the problem is to call asprintf(&s, "%s%s", buf, buf) such that there is sufficient memory for the first copy of buf, but not the second copy. A patch against -STABLE is at the bottom of this message. It should be applicable to -CURRENT as well. This bug raises two points: 1) The *printf() routines could probably use a rewrite. It's hard to say whether there are any other leaks. For example, sometimes memory is allocated in asprintf(), which calls vfprintf(), which uses the PRINT macro to call __sprint(), which calls __sfvwrite(), which is responsible for freeing the said buffer if the program runs out of memory. 2) reallocf(NULL, x) is equivalent to malloc(x), which is the source of this bug. Maybe it shouldn't do that. If it were changed, it would be safe to say p = reallocf(p, x1); ... p = reallocf(p, x2); without the check in the patch below. Index: src/lib/libc/stdio/asprintf.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdio/asprintf.c,v retrieving revision 1.6 diff -u -u -r1.6 asprintf.c --- src/lib/libc/stdio/asprintf.c 1999/08/28 00:00:55 1.6 +++ src/lib/libc/stdio/asprintf.c 2002/09/25 13:08:48 @@ -71,7 +71,8 @@ ret = vfprintf(&f, fmt, ap); *f._p = '\0'; va_end(ap); - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); + if (f._bf._base != NULL) + f._bf._base = reallocf(f._bf._base, f._bf._size + 1); if (f._bf._base == NULL) { errno = ENOMEM; ret = -1; Index: src/lib/libc/stdio/vasprintf.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdio/vasprintf.c,v retrieving revision 1.11 diff -u -u -r1.11 vasprintf.c --- src/lib/libc/stdio/vasprintf.c 1999/08/28 00:01:19 1.11 +++ src/lib/libc/stdio/vasprintf.c 2002/09/25 13:08:48 @@ -55,7 +55,8 @@ f._bf._size = f._w = 127; /* Leave room for the NULL */ ret = vfprintf(&f, fmt, ap); *f._p = '\0'; - f._bf._base = reallocf(f._bf._base, f._bf._size + 1); + if (f._bf._base != NULL) + f._bf._base = reallocf(f._bf._base, f._bf._size + 1); if (f._bf._base == NULL) { errno = ENOMEM; ret = -1; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020925133219.GA59210>