about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-12-29 15:57:15 +0000
committerUlrich Drepper <drepper@redhat.com>2001-12-29 15:57:15 +0000
commitd1dddedf7893fe70ed5d429485c8bcd0ab43f285 (patch)
tree99420c13234130854769150b8d81f5fe1d2528e3
parent9403ec5d23e7dc209361b3dbae2fdc184e1684aa (diff)
downloadglibc-d1dddedf7893fe70ed5d429485c8bcd0ab43f285.tar.gz
glibc-d1dddedf7893fe70ed5d429485c8bcd0ab43f285.tar.xz
glibc-d1dddedf7893fe70ed5d429485c8bcd0ab43f285.zip
Realloc error handling memory leak fix.
-rw-r--r--crypt/md5-crypt.c8
-rw-r--r--elf/chroot_canon.c19
-rw-r--r--elf/dl-object.c11
-rw-r--r--iconv/iconv_charmap.c13
-rw-r--r--iconv/iconv_prog.c11
-rw-r--r--libio/iogetdelim.c11
-rw-r--r--locale/lc-time.c13
-rw-r--r--stdlib/canonicalize.c10
-rw-r--r--sunrpc/svc.c12
-rw-r--r--sysdeps/generic/glob.c42
10 files changed, 100 insertions, 50 deletions
diff --git a/crypt/md5-crypt.c b/crypt/md5-crypt.c
index 018b2df437..0f7f3ecce3 100644
--- a/crypt/md5-crypt.c
+++ b/crypt/md5-crypt.c
@@ -247,9 +247,15 @@ __md5_crypt (const char *key, const char *salt)
 
   if (buflen < needed)
     {
+      char *new_buffer;
+
       buflen = needed;
-      if ((buffer = realloc (buffer, buflen)) == NULL)
+
+      new_buffer = (char *) realloc (buffer, buflen);
+      if (new_buffer == NULL)
 	return NULL;
+
+      buffer = new_buffer;
     }
 
   return __md5_crypt_r (key, salt, buffer, buflen);
diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
index 383c72e651..6b7e444800 100644
--- a/elf/chroot_canon.c
+++ b/elf/chroot_canon.c
@@ -1,5 +1,5 @@
 /* Return the canonical absolute name of a given file inside chroot.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -42,8 +42,13 @@
 char *
 chroot_canon (const char *chroot, const char *name)
 {
-  char *rpath, *dest, *extra_buf = NULL, *rpath_root;
-  const char *start, *end, *rpath_limit;
+  char *rpath;
+  char *dest;
+  char *extra_buf = NULL;
+  char *rpath_root;
+  const char *start;
+  const char *end;
+  const char *rpath_limit;
   int num_links = 0;
   size_t chroot_len = strlen (chroot);
 
@@ -94,16 +99,18 @@ chroot_canon (const char *chroot, const char *name)
 	  if (dest + (end - start) >= rpath_limit)
 	    {
 	      ptrdiff_t dest_offset = dest - rpath;
+	      char *new_rpath;
 
 	      new_size = rpath_limit - rpath;
 	      if (end - start + 1 > PATH_MAX)
 		new_size += end - start + 1;
 	      else
 		new_size += PATH_MAX;
-	      rpath = realloc (rpath, new_size);
-	      rpath_limit = rpath + new_size;
-	      if (rpath == NULL)
+	      new_rpath = (char *) realloc (rpath, new_size);
+	      if (new_rpath == NULL)
 		return NULL;
+	      rpath = new_rpath;
+	      rpath_limit = rpath + new_size;
 
 	      dest = rpath + dest_offset;
 	    }
diff --git a/elf/dl-object.c b/elf/dl-object.c
index ed78b47127..eee9deb3d2 100644
--- a/elf/dl-object.c
+++ b/elf/dl-object.c
@@ -121,11 +121,16 @@ _dl_new_object (char *realname, const char *libname, int type,
 	  origin = NULL;
 	  do
 	    {
+	      char *new_origin;
+
 	      len += 128;
-	      origin = (char *) realloc (origin, len);
+	      new_origin = (char *) realloc (origin, len);
+	      if (new_origin == NULL)
+		/* We exit the loop.  Note that result == NULL.  */
+		break;
+	      origin = new_origin;
 	    }
-	  while (origin != NULL
-		 && (result = __getcwd (origin, len - realname_len)) == NULL
+	  while ((result = __getcwd (origin, len - realname_len)) == NULL
 		 && errno == ERANGE);
 
 	  if (result == NULL)
diff --git a/iconv/iconv_charmap.c b/iconv/iconv_charmap.c
index 141c8eca2d..03a8f5fa23 100644
--- a/iconv/iconv_charmap.c
+++ b/iconv/iconv_charmap.c
@@ -483,7 +483,7 @@ incomplete character or shift sequence at end of buffer"));
 static int
 process_fd (struct convtable *tbl, int fd, FILE *output)
 {
-  /* we have a problem with reading from a desriptor since we must not
+  /* We have a problem with reading from a descriptor since we must not
      provide the iconv() function an incomplete character or shift
      sequence at the end of the buffer.  Since we have to deal with
      arbitrary encodings we must read the whole text in a buffer and
@@ -516,12 +516,17 @@ process_fd (struct convtable *tbl, int fd, FILE *output)
     while (1)
       {
 	ssize_t n;
+	char *new_inbuf;
 
 	/* Increase the buffer.  */
+	new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
+	if (new_inbuf == NULL)
+	  {
+	    error (0, errno, _("unable to allocate buffer for input"));
+	    return -1;
+	  }
+	inbuf = new_inbuf;
 	maxlen += 32768;
-	inbuf = realloc (inbuf, maxlen);
-	if (inbuf == NULL)
-	  error (0, errno, _("unable to allocate buffer for input"));
 	inptr = inbuf + actlen;
 
 	do
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
index 07296f07f0..94743b0d5d 100644
--- a/iconv/iconv_prog.c
+++ b/iconv/iconv_prog.c
@@ -516,12 +516,17 @@ process_fd (iconv_t cd, int fd, FILE *output)
     while (1)
       {
 	ssize_t n;
+	char *new_inbuf;
 
 	/* Increase the buffer.  */
+	new_inbuf = (char *) realloc (inbuf, maxlen + 32768);
+	if (new_inbuf == NULL)
+	  {
+	    error (0, errno, _("unable to allocate buffer for input"));
+	    return -1;
+	  }
+	inbuf = new_inbuf;
 	maxlen += 32768;
-	inbuf = realloc (inbuf, maxlen);
-	if (inbuf == NULL)
-	  error (0, errno, _("unable to allocate buffer for input"));
 	inptr = inbuf + actlen;
 
 	do
diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c
index e648bf0374..edc5228693 100644
--- a/libio/iogetdelim.c
+++ b/libio/iogetdelim.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -96,15 +96,18 @@ _IO_getdelim (lineptr, n, delimiter, fp)
       needed = cur_len + len + 1;
       if (needed > *n)
 	{
+	  char *new_lineptr;
+
 	  if (needed < 2 * *n)
 	    needed = 2 * *n;  /* Be generous. */
-	  *n = needed;
-	  *lineptr = (char *) realloc (*lineptr, needed);
-	  if (*lineptr == NULL)
+	  new_lineptr = (char *) realloc (*lineptr, needed);
+	  if (new_lineptr == NULL)
 	    {
 	      result = -1;
 	      goto unlock_return;
 	    }
+	  *lineptr = new_lineptr;
+	  *n = needed;
 	}
       memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
       fp->_IO_read_ptr += len;
diff --git a/locale/lc-time.c b/locale/lc-time.c
index efa56b8f82..203a49be1f 100644
--- a/locale/lc-time.c
+++ b/locale/lc-time.c
@@ -74,12 +74,16 @@ _nl_init_era_entries (void)
 	}
       else
 	{
+	  struct era_entry *new_eras = eras;
+
 	  if (num_eras != new_num_eras)
-	    eras = (struct era_entry *) realloc (eras,
-						 new_num_eras
-						 * sizeof (struct era_entry));
-	  if (eras == NULL)
+	    new_eras =
+	      (struct era_entry *) realloc (eras,
+					    new_num_eras
+					    * sizeof (struct era_entry));
+	  if (new_eras == NULL)
 	    {
+	      free (eras);
 	      num_eras = 0;
 	      eras = NULL;
 	    }
@@ -87,6 +91,7 @@ _nl_init_era_entries (void)
 	    {
 	      const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES);
 	      num_eras = new_num_eras;
+	      eras = new_eras;
 
 	      for (cnt = 0; cnt < num_eras; ++cnt)
 		{
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 7186ad9458..2098d77df2 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -1,5 +1,5 @@
 /* Return the canonical absolute name of a given file.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -122,6 +122,7 @@ canonicalize (const char *name, char *resolved)
 	  if (dest + (end - start) >= rpath_limit)
 	    {
 	      ptrdiff_t dest_offset = dest - rpath;
+	      char *new_rpath;
 
 	      if (resolved)
 		{
@@ -136,10 +137,11 @@ canonicalize (const char *name, char *resolved)
 		new_size += end - start + 1;
 	      else
 		new_size += path_max;
-	      rpath = realloc (rpath, new_size);
+	      new_rpath = (char *) realloc (rpath, new_size);
+	      if (new_rpath == NULL)
+		goto error;
+	      rpath = new_rpath;
 	      rpath_limit = rpath + new_size;
-	      if (rpath == NULL)
-		return NULL;
 
 	      dest = rpath + dest_offset;
 	    }
diff --git a/sunrpc/svc.c b/sunrpc/svc.c
index 6357d51354..5260634ae2 100644
--- a/sunrpc/svc.c
+++ b/sunrpc/svc.c
@@ -86,6 +86,8 @@ xprt_register (SVCXPRT *xprt)
 
   if (sock < _rpc_dtablesize ())
     {
+      struct pollfd *new_svc_pollfd;
+
       xports[sock] = xprt;
       if (sock < FD_SETSIZE)
 	FD_SET (sock, &svc_fdset);
@@ -100,11 +102,13 @@ xprt_register (SVCXPRT *xprt)
 	    return;
 	  }
 
-      ++svc_max_pollfd;
-      svc_pollfd = realloc (svc_pollfd,
-			    sizeof (struct pollfd) * svc_max_pollfd);
-      if (svc_pollfd == NULL) /* Out of memory */
+      new_svc_pollfd = (struct pollfd *) realloc (svc_pollfd,
+						  sizeof (struct pollfd)
+						  * (svc_max_pollfd + 1));
+      if (new_svc_pollfd == NULL) /* Out of memory */
 	return;
+      svc_pollfd = new_svc_pollfd;
+      ++svc_max_pollfd;
 
       svc_pollfd[svc_max_pollfd - 1].fd = sock;
       svc_pollfd[svc_max_pollfd - 1].events = (POLLIN | POLLPRI |
diff --git a/sysdeps/generic/glob.c b/sysdeps/generic/glob.c
index 5232054a9f..20cf0a2f5b 100644
--- a/sysdeps/generic/glob.c
+++ b/sysdeps/generic/glob.c
@@ -836,28 +836,33 @@ glob (pattern, flags, errfunc, pglob)
 	       : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
 	{
 	  int newcount = pglob->gl_pathc + pglob->gl_offs;
+	  char **new_gl_pathv;
 
-	  pglob->gl_pathv
+	  new_gl_pathv
 	    = (char **) realloc (pglob->gl_pathv,
 				 (newcount + 1 + 1) * sizeof (char *));
-	  if (pglob->gl_pathv == NULL)
-	    return GLOB_NOSPACE;
+	  if (new_gl_pathv == NULL)
+	    {
+	    nospace:
+	      free (pglob->gl_pathv);
+	      pglob->gl_pathv = NULL;
+	      pglob->gl_pathc = 0;
+	      return GLOB_NOSPACE;
+	    }
+	  pglob->gl_pathv = new_gl_pathv;
 
 #if defined HAVE_STRDUP || defined _LIBC
 	   pglob->gl_pathv[newcount] = strdup (dirname);
 #else
 	  {
 	    size_t len = strlen (dirname) + 1;
-	    char *dircopy = malloc (len);
+	    char *dircopy = (char *) malloc (len);
 	    if (dircopy != NULL)
 	      pglob->gl_pathv[newcount] = memcpy (dircopy, dirname, len);
 	  }
 #endif
 	  if (pglob->gl_pathv[newcount] == NULL)
-	    {
-	      free (pglob->gl_pathv);
-	      return GLOB_NOSPACE;
-	    }
+	    goto nospace;
 	  pglob->gl_pathv[++newcount] = NULL;
 	  ++pglob->gl_pathc;
 	  pglob->gl_flags = flags;
@@ -946,24 +951,24 @@ glob (pattern, flags, errfunc, pglob)
 
       /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
 	 But if we have not found any matching entry and the GLOB_NOCHECK
-	 flag was set we must return the list consisting of the disrectory
-	 names followed by the filename.  */
+	 flag was set we must return the input pattern itself.  */
       if (pglob->gl_pathc + pglob->gl_offs == oldcount)
 	{
 	  /* No matches.  */
 	  if (flags & GLOB_NOCHECK)
 	    {
 	      int newcount = pglob->gl_pathc + pglob->gl_offs;
+	      char **new_gl_pathv;
 
-	      pglob->gl_pathv
-		= (char **) realloc (pglob->gl_pathv,
-				     (newcount + 2)
-				     * sizeof (char *));
-	      if (pglob->gl_pathv == NULL)
+	      new_gl_pathv = (char **) realloc (pglob->gl_pathv,
+						(newcount + 2)
+						* sizeof (char *));
+	      if (new_gl_pathv == NULL)
 		{
 		  globfree (&dirs);
 		  return GLOB_NOSPACE;
 		}
+	      pglob->gl_pathv = new_gl_pathv;
 
 	      pglob->gl_pathv[newcount] = __strdup (pattern);
 	      if (pglob->gl_pathv[newcount] == NULL)
@@ -1386,12 +1391,15 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
 
   if (nfound != 0)
     {
-      pglob->gl_pathv
+      char **new_gl_pathv;
+
+      new_gl_pathv
 	= (char **) realloc (pglob->gl_pathv,
 			     (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
 			     * sizeof (char *));
-      if (pglob->gl_pathv == NULL)
+      if (new_gl_pathv == NULL)
 	goto memory_error;
+      pglob->gl_pathv = new_gl_pathv;
 
       for (; names != NULL; names = names->next)
 	pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc++] = names->name;