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>
