estream: Fix unclean usage of realloc.

* common/estream-printf.c (_ESTREAM_PRINTF_MALLOC): Remove.
(_ESTREAM_PRINTF_FREE): Remove.
(_ESTREAM_PRINTF_REALLOC): New.
(fixed_realloc) [!_ESTREAM_PRINTF_REALLOC]): New.
(estream_vasprintf): Use my_printf_realloc instead of my_printf_malloc
and my_printf_free.
(dynamic_buffer_out): Use my_printf_realloc instead of realloc.
--

This bug will never happen in current GnuPG/Libgcrypt because we use
the standard memory allocation functions via Libgcrypt.  However, when
used in other environments it would mess up the heap for an asprintf
with an output length larger than ~512 bytes.
This commit is contained in:
Werner Koch 2012-01-20 14:27:36 +01:00
parent 7589e43b21
commit e97e2ced6c
4 changed files with 39 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/* estream-printf.c - Versatile mostly C-99 compliant printf formatting
* Copyright (C) 2007, 2008, 2009, 2010 g10 Code GmbH
* Copyright (C) 2007, 2008, 2009, 2010, 2012 g10 Code GmbH
*
* This file is part of Libestream.
*
@ -109,16 +109,11 @@
/* #define DEBUG 1 */
/* Allow redefinition of asprintf used malloc functions. */
#if defined(_ESTREAM_PRINTF_MALLOC)
#define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a))
/* Allow redefinition of asprintf used realloc function. */
#if defined(_ESTREAM_PRINTF_REALLOC)
#define my_printf_realloc(a,b) _ESTREAM_PRINTF_REALLOC((a),(b))
#else
#define my_printf_malloc(a) malloc((a))
#endif
#if defined(_ESTREAM_PRINTF_FREE)
#define my_printf_free(a) _ESTREAM_PRINTF_FREE((a))
#else
#define my_printf_free(a) free((a))
#define my_printf_realloc(a,b) fixed_realloc((a),(b))
#endif
/* A wrapper to set ERRNO. */
@ -309,6 +304,26 @@ struct valueitem_s
};
typedef struct valueitem_s *valueitem_t;
/* Not all systems have a C-90 compliant realloc. To cope with this
we use this simple wrapper. */
#ifndef _ESTREAM_PRINTF_REALLOC
static void *
fixed_realloc (void *a, size_t n)
{
if (!a)
return malloc (n);
if (!n)
{
free (a);
return NULL;
}
return realloc (a, n);
}
#endif /*!_ESTREAM_PRINTF_REALLOC*/
#ifdef DEBUG
static void
@ -1762,7 +1777,7 @@ dynamic_buffer_out (void *outfncarg, const char *buf, size_t buflen)
char *p;
parm->alloced += buflen + 512;
p = realloc (parm->buffer, parm->alloced);
p = my_printf_realloc (parm->buffer, parm->alloced);
if (!p)
{
parm->error_flag = errno ? errno : ENOMEM;
@ -1792,7 +1807,7 @@ estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
parm.error_flag = 0;
parm.alloced = 512;
parm.used = 0;
parm.buffer = my_printf_malloc (parm.alloced);
parm.buffer = my_printf_realloc (NULL, parm.alloced);
if (!parm.buffer)
{
*bufp = NULL;
@ -1811,7 +1826,8 @@ estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
if (rc == -1)
{
memset (parm.buffer, 0, parm.used);
my_printf_free (parm.buffer);
if (parm.buffer)
my_printf_realloc (parm.buffer, 0);
*bufp = NULL;
return -1;
}

View File

@ -1,5 +1,5 @@
/* estream-printf.h - Versatile mostly C-99 compliant printf formatting.
* Copyright (C) 2007, 2010 g10 Code GmbH
* Copyright (C) 2007, 2010, 2012 g10 Code GmbH
*
* This file is part of Libestream.
*
@ -66,12 +66,13 @@
For the implementation of the code (estream-printf.c) the following
macros may be used to tune the implementation for certain systems:
#define _ESTREAM_PRINTF_MALLOC foo_malloc
#define _ESTREAM_PRINTF_FREE foo_free
#define _ESTREAM_PRINTF_REALLOC foo_realloc
Make estream_asprintf and estream_vasprintf use foo_malloc and
foo_free instead of the standard malloc and free functions to
allocate the memory returned to the caller.
Make estream_asprintf and estream_vasprintf use foo_realloc
instead of the standard realloc to allocate memory returned to
the caller. Note that foo_realloc needs to be C-90 compliant:
foo_realloc (NULL,n) is the same as a call to malloc(n) and
foo_realloc (a, 0) is the same as a call to free (a).
#define _ESTREAM_PRINTF_EXTRA_INCLUDE "foo.h"

View File

@ -24,8 +24,8 @@
#include "util.h"
#include "iobuf.h"
#if !defined(_ESTREAM_PRINTF_MALLOC) || !defined(_ESTREAM_PRINTF_FREE)
#error Need to define ESTREAM_PRINTF_MALLOC and _FREE
#if !defined(_ESTREAM_PRINTF_REALLOC)
#error Need to define _ESTREAM_PRINTF_REALLOC
#endif
/* Same as asprintf but return an allocated buffer suitable to be

View File

@ -511,8 +511,7 @@ AH_BOTTOM([
/* We want to use the libgcrypt provided memory allocation for
asprintf. */
#define _ESTREAM_PRINTF_MALLOC gcry_malloc
#define _ESTREAM_PRINTF_FREE gcry_free
#define _ESTREAM_PRINTF_REALLOC gcry_realloc
#define _ESTREAM_PRINTF_EXTRA_INCLUDE "../common/util.h"
/* Under Windows we use the gettext code from libgpg-error. */