[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

r6229 - glibc-package/branches/glibc-branch-wheezy/debian/patches/any



Author: aurel32
Date: 2014-08-14 13:41:03 +0000 (Thu, 14 Aug 2014)
New Revision: 6229

Added:
   glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4357.diff
Log:
Add missing patch in previous commit


Added: glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4357.diff
===================================================================
--- glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4357.diff	                        (rev 0)
+++ glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4357.diff	2014-08-14 13:41:03 UTC (rev 6229)
@@ -0,0 +1,849 @@
+2011-05-22  Ulrich Drepper  <drepper@gmail.com>
+ 
+	[BZ #12671]
+	* nis/nss_nis/nis-alias.c (_nss_nis_getaliasbyname_r): Use malloc in
+	some situations.
+	* nscd/nscd_getserv_r.c (nscd_getserv_r): Likewise.
+	* posix/glob.c (glob_in_dir): Take additional parameter alloca_used.
+	add in in __libc_use_alloca calls.  Adjust callers.
+	(glob): Use malloc in some situations.
+
+--- a/nis/nss_nis/nis-alias.c
++++ b/nis/nss_nis/nis-alias.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1996-2002, 2003, 2006 Free Software Foundation, Inc.
++/* Copyright (C) 1996-2002, 2003, 2006, 2011 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ 
+@@ -142,10 +142,10 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
+       int yperr;
+ 
+       if (new_start)
+-        yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result,
++	yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result,
+ 			  &len);
+       else
+-        yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey,
++	yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey,
+ 			 &keylen, &result, &len);
+ 
+       if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
+@@ -153,20 +153,20 @@ internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
+ 	  enum nss_status retval = yperr2nss (yperr);
+ 
+ 	  if (retval == NSS_STATUS_TRYAGAIN)
+-            *errnop = errno;
+-          return retval;
+-        }
++	    *errnop = errno;
++	  return retval;
++	}
+ 
+       if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
+-        {
++	{
+ 	  free (result);
+-          *errnop = ERANGE;
+-          return NSS_STATUS_TRYAGAIN;
+-        }
++	  *errnop = ERANGE;
++	  return NSS_STATUS_TRYAGAIN;
++	}
+       char *p = strncpy (buffer, result, len);
+       buffer[len] = '\0';
+       while (isspace (*p))
+-        ++p;
++	++p;
+       free (result);
+ 
+       parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer,
+@@ -213,13 +213,25 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
+       return NSS_STATUS_UNAVAIL;
+     }
+ 
+-  size_t namlen = strlen (name);
+-  char name2[namlen + 1];
+-
+   char *domain;
+   if (__builtin_expect (yp_get_default_domain (&domain), 0))
+     return NSS_STATUS_UNAVAIL;
+ 
++  size_t namlen = strlen (name);
++  char *name2;
++  int use_alloca = __libc_use_alloca (namlen + 1);
++  if (use_alloca)
++    name2 = __alloca (namlen + 1);
++  else
++    {
++      name2 = malloc (namlen + 1);
++      if (name2 == NULL)
++	{
++	  *errnop = ENOMEM;
++	  return NSS_STATUS_TRYAGAIN;
++	}
++    }
++
+   /* Convert name to lowercase.  */
+   size_t i;
+   for (i = 0; i < namlen; ++i)
+@@ -230,6 +242,9 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
+   int len;
+   int yperr = yp_match (domain, "mail.aliases", name2, namlen, &result, &len);
+ 
++  if (!use_alloca)
++    free (name2);
++
+   if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
+     {
+       enum nss_status retval = yperr2nss (yperr);
+--- a/nscd/nscd_getserv_r.c
++++ b/nscd/nscd_getserv_r.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2007, 2009 Free Software Foundation, Inc.
++/* Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
+ 
+@@ -17,6 +17,7 @@
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
++#include <assert.h>
+ #include <errno.h>
+ #include <string.h>
+ #include <not-cancel.h>
+@@ -80,6 +81,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
+ {
+   int gc_cycle;
+   int nretries = 0;
++  size_t alloca_used = 0;
+ 
+   /* If the mapping is available, try to search there instead of
+      communicating with the nscd.  */
+@@ -88,13 +90,23 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
+ 			       &gc_cycle);
+   size_t protolen = proto == NULL ? 0 : strlen (proto);
+   size_t keylen = critlen + 1 + protolen + 1;
+-  char *key = alloca (keylen);
++  int alloca_key = __libc_use_alloca (keylen);
++  char *key;
++  if (alloca_key)
++    key = alloca_account (keylen, alloca_used);
++  else
++    {
++      key = malloc (keylen);
++      if (key == NULL)
++	return -1;
++    }
+   memcpy (__mempcpy (__mempcpy (key, crit, critlen),
+ 		     "/", 1), proto ?: "", protolen + 1);
+ 
+  retry:;
+   const char *s_name = NULL;
+   const char *s_proto = NULL;
++  int alloca_aliases_len = 0;
+   const uint32_t *aliases_len = NULL;
+   const char *aliases_list = NULL;
+   int retval = -1;
+@@ -136,8 +148,22 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
+ 	  if (((uintptr_t) aliases_len & (__alignof__ (*aliases_len) - 1))
+ 	      != 0)
+ 	    {
+-	      uint32_t *tmp = alloca (serv_resp.s_aliases_cnt
+-				      * sizeof (uint32_t));
++	      uint32_t *tmp;
++	      alloca_aliases_len
++		= __libc_use_alloca (alloca_used
++				     + (serv_resp.s_aliases_cnt
++					* sizeof (uint32_t)));
++	      if (alloca_aliases_len)
++		tmp = __alloca (serv_resp.s_aliases_cnt * sizeof (uint32_t));
++	      else
++		{
++		  tmp = malloc (serv_resp.s_aliases_cnt * sizeof (uint32_t));
++		  if (tmp == NULL)
++		    {
++		      retval = ENOMEM;
++		      goto out;
++		    }
++		}
+ 	      aliases_len = memcpy (tmp, aliases_len,
+ 				    serv_resp.s_aliases_cnt
+ 				    * sizeof (uint32_t));
+@@ -217,8 +243,24 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
+ 
+ 	  if (serv_resp.s_aliases_cnt > 0)
+ 	    {
+-	      aliases_len = alloca (serv_resp.s_aliases_cnt
+-				    * sizeof (uint32_t));
++	      assert (alloca_aliases_len == 0);
++	      alloca_aliases_len
++		= __libc_use_alloca (alloca_used
++				     + (serv_resp.s_aliases_cnt
++					* sizeof (uint32_t)));
++	      if (alloca_aliases_len)
++		aliases_len = alloca (serv_resp.s_aliases_cnt
++				      * sizeof (uint32_t));
++	      else
++		{
++		  aliases_len = malloc (serv_resp.s_aliases_cnt
++					* sizeof (uint32_t));
++		  if (aliases_len == NULL)
++		    {
++		      retval = ENOMEM;
++		      goto out_close;
++		    }
++		}
+ 	      vec[n].iov_base = (void *) aliases_len;
+ 	      vec[n].iov_len = serv_resp.s_aliases_cnt * sizeof (uint32_t);
+ 
+@@ -329,5 +371,10 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
+ 	goto retry;
+     }
+ 
++  if (!alloca_aliases_len)
++    free ((void *) aliases_len);
++  if (!alloca_key)
++    free (key);
++
+   return retval;
+ }
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
++/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
+    Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+@@ -199,7 +199,7 @@ static const char *next_brace_sub (const char *begin, int flags) __THROW;
+ 
+ static int glob_in_dir (const char *pattern, const char *directory,
+ 			int flags, int (*errfunc) (const char *, int),
+-			glob_t *pglob);
++			glob_t *pglob, size_t alloca_used);
+ extern int __glob_pattern_type (const char *pattern, int quote)
+     attribute_hidden;
+ 
+@@ -253,13 +253,18 @@ glob (pattern, flags, errfunc, pglob)
+      glob_t *pglob;
+ {
+   const char *filename;
+-  const char *dirname;
++  char *dirname = NULL;
+   size_t dirlen;
+   int status;
+   size_t oldcount;
+   int meta;
+   int dirname_modified;
++  int malloc_dirname = 0;
+   glob_t dirs;
++  int retval = 0;
++#ifdef _LIBC
++  size_t alloca_used = 0;
++#endif
+ 
+   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
+     {
+@@ -308,20 +313,26 @@ glob (pattern, flags, errfunc, pglob)
+ 	  const char *next;
+ 	  const char *rest;
+ 	  size_t rest_len;
+-#ifdef __GNUC__
+-	  char onealt[strlen (pattern) - 1];
+-#else
+-	  char *onealt = (char *) malloc (strlen (pattern) - 1);
+-	  if (onealt == NULL)
++	  char *onealt;
++	  size_t pattern_len = strlen (pattern) - 1;
++#ifdef _LIBC
++	  int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len);
++	  if (alloca_onealt)
++	    onealt = alloca_account (pattern_len, alloca_used);
++	  else
++#endif
+ 	    {
+-	      if (!(flags & GLOB_APPEND))
++	      onealt = (char *) malloc (pattern_len);
++	      if (onealt == NULL)
+ 		{
+-		  pglob->gl_pathc = 0;
+-		  pglob->gl_pathv = NULL;
++		  if (!(flags & GLOB_APPEND))
++		    {
++		      pglob->gl_pathc = 0;
++		      pglob->gl_pathv = NULL;
++		    }
++		  return GLOB_NOSPACE;
+ 		}
+-	      return GLOB_NOSPACE;
+ 	    }
+-#endif
+ 
+ 	  /* We know the prefix for all sub-patterns.  */
+ 	  alt_start = mempcpy (onealt, pattern, begin - pattern);
+@@ -332,9 +343,11 @@ glob (pattern, flags, errfunc, pglob)
+ 	  if (next == NULL)
+ 	    {
+ 	      /* It is an illegal expression.  */
+-#ifndef __GNUC__
+-	      free (onealt);
++	    illegal_brace:
++#ifdef _LIBC
++	      if (__builtin_expect (!alloca_onealt, 0))
+ #endif
++		free (onealt);
+ 	      return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
+ 	    }
+ 
+@@ -344,13 +357,8 @@ glob (pattern, flags, errfunc, pglob)
+ 	    {
+ 	      rest = next_brace_sub (rest + 1, flags);
+ 	      if (rest == NULL)
+-		{
+-		  /* It is an illegal expression.  */
+-#ifndef __GNUC__
+-		  free (onealt);
+-#endif
+-		  return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
+-		}
++		/* It is an illegal expression.  */
++		goto illegal_brace;
+ 	    }
+ 	  /* Please note that we now can be sure the brace expression
+ 	     is well-formed.  */
+@@ -386,9 +394,10 @@ glob (pattern, flags, errfunc, pglob)
+ 	      /* If we got an error, return it.  */
+ 	      if (result && result != GLOB_NOMATCH)
+ 		{
+-#ifndef __GNUC__
+-		  free (onealt);
++#ifdef _LIBC
++		  if (__builtin_expect (!alloca_onealt, 0))
+ #endif
++		    free (onealt);
+ 		  if (!(flags & GLOB_APPEND))
+ 		    {
+ 		      globfree (pglob);
+@@ -406,9 +415,10 @@ glob (pattern, flags, errfunc, pglob)
+ 	      assert (next != NULL);
+ 	    }
+ 
+-#ifndef __GNUC__
+-	  free (onealt);
++#ifdef _LIBC
++	  if (__builtin_expect (!alloca_onealt, 0))
+ #endif
++	    free (onealt);
+ 
+ 	  if (pglob->gl_pathc != firstc)
+ 	    /* We found some entries.  */
+@@ -455,7 +465,7 @@ glob (pattern, flags, errfunc, pglob)
+ 	 case is nothing but a notation for a directory.  */
+       if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
+ 	{
+-	  dirname = pattern;
++	  dirname = (char *) pattern;
+ 	  dirlen = strlen (pattern);
+ 
+ 	  /* Set FILENAME to NULL as a special flag.  This is ugly but
+@@ -473,9 +483,9 @@ glob (pattern, flags, errfunc, pglob)
+ 
+ 	  filename = pattern;
+ #ifdef _AMIGA
+-	  dirname = "";
++	  dirname = (char *) "";
+ #else
+-	  dirname = ".";
++	  dirname = (char *) ".";
+ #endif
+ 	  dirlen = 0;
+ 	}
+@@ -485,7 +495,7 @@ glob (pattern, flags, errfunc, pglob)
+ 	       && (flags & GLOB_NOESCAPE) == 0))
+     {
+       /* "/pattern" or "\\/pattern".  */
+-      dirname = "/";
++      dirname = (char *) "/";
+       dirlen = 1;
+       ++filename;
+     }
+@@ -511,7 +521,17 @@ glob (pattern, flags, errfunc, pglob)
+ 	     from "d:/", since "d:" and "d:/" are not the same.*/
+ 	}
+ #endif
+-      newp = (char *) __alloca (dirlen + 1);
++#ifdef _LIBC
++      if (__libc_use_alloca (alloca_used + dirlen + 1))
++	newp = alloca_account (dirlen + 1, alloca_used);
++      else
++#endif
++	{
++	  newp = malloc (dirlen + 1);
++	  if (newp == NULL)
++	    return GLOB_NOSPACE;
++	  malloc_dirname = 1;
++	}
+       *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
+       dirname = newp;
+       ++filename;
+@@ -551,7 +571,8 @@ glob (pattern, flags, errfunc, pglob)
+ 	      oldcount = pglob->gl_pathc + pglob->gl_offs;
+ 	      goto no_matches;
+ 	    }
+-	  return val;
++	  retval = val;
++	  goto out;
+ 	}
+     }
+ 
+@@ -563,7 +584,8 @@ glob (pattern, flags, errfunc, pglob)
+ 	      && (dirname[2] == '\0' || dirname[2] == '/')))
+ 	{
+ 	  /* Look up home directory.  */
+-	  const char *home_dir = getenv ("HOME");
++	  char *home_dir = getenv ("HOME");
++	  int malloc_home_dir = 0;
+ # ifdef _AMIGA
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    home_dir = "SYS:";
+@@ -582,7 +604,7 @@ glob (pattern, flags, errfunc, pglob)
+ 		/* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
+ 		   a moderate value.  */
+ 		buflen = 20;
+-	      name = (char *) __alloca (buflen);
++	      name = alloca_account (buflen, alloca_used);
+ 
+ 	      success = getlogin_r (name, buflen) == 0;
+ 	      if (success)
+@@ -592,6 +614,7 @@ glob (pattern, flags, errfunc, pglob)
+ 		  long int pwbuflen = GETPW_R_SIZE_MAX ();
+ 		  char *pwtmpbuf;
+ 		  struct passwd pwbuf;
++		  int malloc_pwtmpbuf = 0;
+ 		  int save = errno;
+ 
+ #     ifndef _LIBC
+@@ -600,7 +623,18 @@ glob (pattern, flags, errfunc, pglob)
+ 		       Try a moderate value.  */
+ 		    pwbuflen = 1024;
+ #     endif
+-		  pwtmpbuf = (char *) __alloca (pwbuflen);
++		  if (__libc_use_alloca (alloca_used + pwbuflen))
++		    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
++		  else
++		    {
++		      pwtmpbuf = malloc (pwbuflen);
++		      if (pwtmpbuf == NULL)
++			{
++			  retval = GLOB_NOSPACE;
++			  goto out;
++			}
++		      malloc_pwtmpbuf = 1;
++		    }
+ 
+ 		  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
+ 			 != 0)
+@@ -610,47 +644,116 @@ glob (pattern, flags, errfunc, pglob)
+ 			  p = NULL;
+ 			  break;
+ 			}
+-#     ifdef _LIBC
+-		      pwtmpbuf = extend_alloca (pwtmpbuf, pwbuflen,
++
++		      if (!malloc_pwtmpbuf
++			  && __libc_use_alloca (alloca_used
++						+ 2 * pwbuflen))
++			pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
++							  2 * pwbuflen,
++							  alloca_used);
++		      else
++			{
++			  char *newp = realloc (malloc_pwtmpbuf
++						? pwtmpbuf : NULL,
+ 						2 * pwbuflen);
+-#     else
+-		      pwbuflen *= 2;
+-		      pwtmpbuf = (char *) __alloca (pwbuflen);
+-#     endif
++			  if (newp == NULL)
++			    {
++			      if (__builtin_expect (malloc_pwtmpbuf, 0))
++				free (pwtmpbuf);
++			      retval = GLOB_NOSPACE;
++			      goto out;
++			    }
++			  pwtmpbuf = newp;
++			  pwbuflen = 2 * pwbuflen;
++			  malloc_pwtmpbuf = 1;
++			}
+ 		      __set_errno (save);
+ 		    }
+ #    else
+ 		  p = getpwnam (name);
+ #    endif
+ 		  if (p != NULL)
+-		    home_dir = p->pw_dir;
++		    {
++		      if (!malloc_pwtmpbuf)
++			home_dir = p->pw_dir;
++		      else
++			{
++			  size_t home_dir_len = strlen (p->pw_dir) + 1;
++			  if (__libc_use_alloca (alloca_used + home_dir_len))
++			    home_dir = alloca_account (home_dir_len,
++						       alloca_used);
++			  else
++			    {
++			      home_dir = malloc (home_dir_len);
++			      if (home_dir == NULL)
++				{
++				  free (pwtmpbuf);
++				  retval = GLOB_NOSPACE;
++				  goto out;
++				}
++			      malloc_home_dir = 1;
++			    }
++			  memcpy (home_dir, p->pw_dir, home_dir_len);
++
++			  free (pwtmpbuf);
++			}
++		    }
+ 		}
+ 	    }
+ #   endif /* ! _LIBC || __OPTION_EGLIBC_GETLOGIN */
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
+ 	    {
+ 	      if (flags & GLOB_TILDE_CHECK)
+-		return GLOB_NOMATCH;
++		{
++		  if (__builtin_expect (malloc_home_dir, 0))
++		    free (home_dir);
++		  retval = GLOB_NOMATCH;
++		  goto out;
++		}
+ 	      else
+-		home_dir = "~"; /* No luck.  */
++		home_dir = (char *) "~"; /* No luck.  */
+ 	    }
+ #  endif /* WINDOWS32 */
+ # endif
+ 	  /* Now construct the full directory.  */
+ 	  if (dirname[1] == '\0')
+ 	    {
++	      if (__builtin_expect (malloc_dirname, 0))
++		free (dirname);
++
+ 	      dirname = home_dir;
+ 	      dirlen = strlen (dirname);
++	      malloc_dirname = malloc_home_dir;
+ 	    }
+ 	  else
+ 	    {
+ 	      char *newp;
+ 	      size_t home_len = strlen (home_dir);
+-	      newp = (char *) __alloca (home_len + dirlen);
++	      int use_alloca = __libc_use_alloca (alloca_used
++						  + home_len + dirlen);
++	      if (use_alloca)
++		newp = alloca_account (home_len + dirlen, alloca_used);
++	      else
++		{
++		  newp = malloc (home_len + dirlen);
++		  if (newp == NULL)
++		    {
++		      if (__builtin_expect (malloc_home_dir, 0))
++			free (home_dir);
++		      retval = GLOB_NOSPACE;
++		      goto out;
++		    }
++		}
++
+ 	      mempcpy (mempcpy (newp, home_dir, home_len),
+ 		       &dirname[1], dirlen);
++
++	      if (__builtin_expect (malloc_dirname, 0))
++		free (dirname);
++
+ 	      dirname = newp;
+ 	      dirlen += home_len - 1;
++	      malloc_dirname = !use_alloca;
+ 	    }
+ 	  dirname_modified = 1;
+ 	}
+@@ -657,7 +760,8 @@ glob (pattern, flags, errfunc, pglob)
+       else
+ 	{
+ 	  char *end_name = strchr (dirname, '/');
+-	  const char *user_name;
++	  char *user_name;
++	  int malloc_user_name = 0;
+ 	  const char *home_dir;
+ 	  char *unescape = NULL;
+ 
+@@ -677,7 +781,18 @@ glob (pattern, flags, errfunc, pglob)
+ 	  else
+ 	    {
+ 	      char *newp;
+-	      newp = (char *) __alloca (end_name - dirname);
++	      if (__libc_use_alloca (alloca_used + (end_name - dirname)))
++		newp = alloca_account (end_name - dirname, alloca_used);
++	      else
++		{
++		  newp = malloc (end_name - dirname);
++		  if (newp == NULL)
++		    {
++		      retval = GLOB_NOSPACE;
++		      goto out;
++		    }
++		  malloc_user_name = 1;
++		}
+ 	      if (unescape != NULL)
+ 		{
+ 		  char *p = mempcpy (newp, dirname + 1,
+@@ -714,6 +829,7 @@ glob (pattern, flags, errfunc, pglob)
+ #  if defined HAVE_GETPWNAM_R || defined _LIBC
+ 	    long int buflen = GETPW_R_SIZE_MAX ();
+ 	    char *pwtmpbuf;
++	    int malloc_pwtmpbuf = 0;
+ 	    struct passwd pwbuf;
+ 	    int save = errno;
+ 
+@@ -723,7 +839,21 @@ glob (pattern, flags, errfunc, pglob)
+ 		 moderate value.  */
+ 	      buflen = 1024;
+ #   endif
+-	    pwtmpbuf = (char *) __alloca (buflen);
++	    if (__libc_use_alloca (alloca_used + buflen))
++	      pwtmpbuf = alloca_account (buflen, alloca_used);
++	    else
++	      {
++		pwtmpbuf = malloc (buflen);
++		if (pwtmpbuf == NULL)
++		  {
++		  nomem_getpw:
++		    if (__builtin_expect (malloc_user_name, 0))
++		      free (user_name);
++		    retval = GLOB_NOSPACE;
++		    goto out;
++		  }
++		malloc_pwtmpbuf = 1;
++	      }
+ 
+ 	    while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
+ 	      {
+@@ -732,40 +862,77 @@ glob (pattern, flags, errfunc, pglob)
+ 		    p = NULL;
+ 		    break;
+ 		  }
+-#   ifdef _LIBC
+-		pwtmpbuf = extend_alloca (pwtmpbuf, buflen, 2 * buflen);
+-#   else
+-		buflen *= 2;
+-		pwtmpbuf = __alloca (buflen);
+-#   endif
++		if (!malloc_pwtmpbuf
++		    && __libc_use_alloca (alloca_used + 2 * buflen))
++		  pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
++						    2 * buflen, alloca_used);
++		else
++		  {
++		    char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL,
++					  2 * buflen);
++		    if (newp == NULL)
++		      {
++			if (__builtin_expect (malloc_pwtmpbuf, 0))
++			  free (pwtmpbuf);
++			goto nomem_getpw;
++		      }
++		    pwtmpbuf = newp;
++		    malloc_pwtmpbuf = 1;
++		  }
+ 		__set_errno (save);
+ 	      }
+ #  else
+ 	    p = getpwnam (user_name);
+ #  endif
++
++	    if (__builtin_expect (malloc_user_name, 0))
++	      free (user_name);
++
++	    /* If we found a home directory use this.  */
+ 	    if (p != NULL)
+-	      home_dir = p->pw_dir;
++	      {
++		size_t home_len = strlen (p->pw_dir);
++		size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
++
++		if (__builtin_expect (malloc_dirname, 0))
++		  free (dirname);
++		malloc_dirname = 0;
++
++		if (__libc_use_alloca (alloca_used + home_len + rest_len + 1))
++		  dirname = alloca_account (home_len + rest_len + 1,
++					    alloca_used);
++		else
++		  {
++		    dirname = malloc (home_len + rest_len + 1);
++		    if (dirname == NULL)
++		      {
++			if (__builtin_expect (malloc_pwtmpbuf, 0))
++			  free (pwtmpbuf);
++			retval = GLOB_NOSPACE;
++			goto out;
++		      }
++		    malloc_dirname = 1;
++		  }
++		*((char *) mempcpy (mempcpy (dirname, p->pw_dir, home_len),
++				    end_name, rest_len)) = '\0';
++
++		dirlen = home_len + rest_len;
++		dirname_modified = 1;
++
++		if (__builtin_expect (malloc_pwtmpbuf, 0))
++		  free (pwtmpbuf);
++	      }
+ 	    else
+-	      home_dir = NULL;
++	      {
++		if (__builtin_expect (malloc_pwtmpbuf, 0))
++		  free (pwtmpbuf);
++
++		if (flags & GLOB_TILDE_CHECK)
++		  /* We have to regard it as an error if we cannot find the
++		     home directory.  */
++		  return GLOB_NOMATCH;
++	      }
+ 	  }
+-	  /* If we found a home directory use this.  */
+-	  if (home_dir != NULL)
+-	    {
+-	      char *newp;
+-	      size_t home_len = strlen (home_dir);
+-	      size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
+-	      newp = (char *) __alloca (home_len + rest_len + 1);
+-	      *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
+-				  end_name, rest_len)) = '\0';
+-	      dirname = newp;
+-	      dirlen = home_len + rest_len;
+-	      dirname_modified = 1;
+-	    }
+-	  else
+-	    if (flags & GLOB_TILDE_CHECK)
+-	      /* We have to regard it as an error if we cannot find the
+-		 home directory.  */
+-	      return GLOB_NOMATCH;
+ 	}
+ # endif	/* Not Amiga && not WINDOWS32.  */
+     }
+@@ -899,7 +1066,7 @@ glob (pattern, flags, errfunc, pglob)
+ 	  status = glob_in_dir (filename, dirs.gl_pathv[i],
+ 				((flags | GLOB_APPEND)
+ 				 & ~(GLOB_NOCHECK | GLOB_NOMAGIC)),
+-				errfunc, pglob);
++				errfunc, pglob, alloca_used);
+ 	  if (status == GLOB_NOMATCH)
+ 	    /* No matches in this directory.  Try the next.  */
+ 	    continue;
+@@ -1000,7 +1167,8 @@ glob (pattern, flags, errfunc, pglob)
+ 	}
+       if (dirname_modified)
+ 	flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
+-      status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
++      status = glob_in_dir (filename, dirname, flags, errfunc, pglob,
++			    alloca_used);
+       if (status != 0)
+ 	{
+ 	  if (status == GLOB_NOMATCH && flags != orig_flags
+@@ -1063,7 +1231,11 @@ glob (pattern, flags, errfunc, pglob)
+ 	     sizeof (char *), collated_compare);
+     }
+ 
+-  return 0;
++ out:
++  if (__builtin_expect (malloc_dirname, 0))
++    free (dirname);
++
++  return retval;
+ }
+ #if defined _LIBC && !defined glob
+ libc_hidden_def (glob)
+@@ -1273,7 +1445,7 @@ link_exists2_p (const char *dir, size_t dirlen, const char *fname,
+ static int
+ glob_in_dir (const char *pattern, const char *directory, int flags,
+ 	     int (*errfunc) (const char *, int),
+-	     glob_t *pglob)
++	     glob_t *pglob, size_t alloca_used)
+ {
+   size_t dirlen = strlen (directory);
+   void *stream = NULL;
+@@ -1288,11 +1460,12 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+   struct globnames *names = &init_names;
+   struct globnames *names_alloca = &init_names;
+   size_t nfound = 0;
+-  size_t allocasize = sizeof (init_names);
+   size_t cur = 0;
+   int meta;
+   int save;
+ 
++  alloca_used += sizeof (init_names);
++
+   init_names.next = NULL;
+   init_names.count = INITIAL_COUNT;
+ 
+@@ -1308,20 +1481,36 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+     {
+       /* Since we use the normal file functions we can also use stat()
+ 	 to verify the file is there.  */
+-      struct stat st;
+-      struct_stat64 st64;
++      union
++      {
++	struct stat st;
++	struct_stat64 st64;
++      } ust;
+       size_t patlen = strlen (pattern);
+-      char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
++      int alloca_fullname = __libc_use_alloca (alloca_used
++					       + dirlen + 1 + patlen + 1);
++      char *fullname;
++      if (alloca_fullname)
++	fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used);
++      else
++	{
++	  fullname = malloc (dirlen + 1 + patlen + 1);
++	  if (fullname == NULL)
++	    return GLOB_NOSPACE;
++	}
+ 
+       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
+ 			"/", 1),
+ 	       pattern, patlen + 1);
+       if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
+-	   ? (*pglob->gl_stat) (fullname, &st)
+-	   : __stat64 (fullname, &st64)) == 0)
++	   ? (*pglob->gl_stat) (fullname, &ust.st)
++	   : __stat64 (fullname, &ust.st64)) == 0)
+ 	/* We found this file to be existing.  Now tell the rest
+ 	   of the function to copy this name into the result.  */
+ 	flags |= GLOB_NOCHECK;
++
++      if (__builtin_expect (!alloca_fullname, 0))
++	free (fullname);
+     }
+   else
+     {
+@@ -1409,9 +1598,9 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
+ 			  size_t size = (sizeof (struct globnames)
+ 					 + ((count - INITIAL_COUNT)
+ 					    * sizeof (char *)));
+-			  allocasize += size;
+-			  if (__libc_use_alloca (allocasize))
+-			    newnames = names_alloca = __alloca (size);
++			  if (__libc_use_alloca (alloca_used + size))
++			    newnames = names_alloca
++			      = alloca_account (size, alloca_used);
+ 			  else if ((newnames = malloc (size))
+ 				   == NULL)
+ 			    goto memory_error;


Reply to: