Skip site navigation (1)Skip section navigation (2)
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>