From owner-freebsd-stable Wed Sep 25 6:32:23 2002 Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7E93F37B404 for ; Wed, 25 Sep 2002 06:32:21 -0700 (PDT) Received: from HAL9000.homeunix.com (12-232-220-15.client.attbi.com [12.232.220.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id A1C1E43E65 for ; Wed, 25 Sep 2002 06:32:20 -0700 (PDT) (envelope-from dschultz@uclink.Berkeley.EDU) Received: from HAL9000.homeunix.com (localhost [127.0.0.1]) by HAL9000.homeunix.com (8.12.6/8.12.5) with ESMTP id g8PDWJ8E059280 for ; Wed, 25 Sep 2002 06:32:19 -0700 (PDT) (envelope-from dschultz@uclink.Berkeley.EDU) Received: (from das@localhost) by HAL9000.homeunix.com (8.12.6/8.12.5/Submit) id g8PDWJPG059279 for stable@FreeBSD.ORG; Wed, 25 Sep 2002 06:32:19 -0700 (PDT) (envelope-from dschultz@uclink.Berkeley.EDU) Date: Wed, 25 Sep 2002 06:32:19 -0700 From: David Schultz To: stable@FreeBSD.ORG Subject: [v]asprintf leaks memory Message-ID: <20020925133219.GA59210@HAL9000.homeunix.com> Mail-Followup-To: stable@FreeBSD.ORG Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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