2012-09-25  Joseph Myers  <joseph@codesourcery.com>

	[BZ #14621]
	* posix/glob.c (next_brace_sub): Use size_t instead of unsigned
	int as type of variable DEPTH.
	(glob): Use size_t instead of int as type of variables NEWCOUNT
	and OLD_PATHC.

2011-07-20  Ulrich Drepper  <drepper@gmail.com>

	[BZ #12852]
	* posix/glob.c (glob): Check passed in values before using them in
	expressions to avoid some overflows.
	(glob_in_dir): Likewise.

Index: glibc-2.11.1/posix/glob.c
===================================================================
--- glibc-2.11.1.orig/posix/glob.c
+++ glibc-2.11.1/posix/glob.c
@@ -46,6 +46,12 @@
 
 #include <pwd.h>
 
+#if defined HAVE_STDINT_H || defined _LIBC
+# include <stdint.h>
+#elif !defined UINTPTR_MAX
+# define UINTPTR_MAX (~((size_t) 0))
+#endif
+
 #include <errno.h>
 #ifndef __set_errno
 # define __set_errno(val) errno = (val)
@@ -212,7 +218,7 @@ static int collated_compare (const void
 static const char *
 next_brace_sub (const char *cp, int flags)
 {
-  unsigned int depth = 0;
+  size_t depth = 0;
   while (*cp != '\0')
     if ((flags & GLOB_NOESCAPE) == 0 && *cp == '\\')
       {
@@ -537,6 +543,10 @@ glob (pattern, flags, errfunc, pglob)
       else
 	{
 	  size_t i;
+
+	  if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *))
+	    return GLOB_NOSPACE;
+
 	  pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1)
 					      * sizeof (char *));
 	  if (pglob->gl_pathv == NULL)
@@ -779,13 +789,11 @@ glob (pattern, flags, errfunc, pglob)
 		  && S_ISDIR (st.st_mode))
 	       : (__stat64 (dirname, &st64) == 0 && S_ISDIR (st64.st_mode)))))
 	{
-	  int newcount = pglob->gl_pathc + pglob->gl_offs;
+	  size_t newcount = pglob->gl_pathc + pglob->gl_offs;
 	  char **new_gl_pathv;
 
-	  new_gl_pathv
-	    = (char **) realloc (pglob->gl_pathv,
-				 (newcount + 1 + 1) * sizeof (char *));
-	  if (new_gl_pathv == NULL)
+	  if (newcount > UINTPTR_MAX - (1 + 1)
+	      || newcount + 1 + 1 > ~((size_t) 0) / sizeof (char *))
 	    {
 	    nospace:
 	      free (pglob->gl_pathv);
@@ -793,6 +801,12 @@ glob (pattern, flags, errfunc, pglob)
 	      pglob->gl_pathc = 0;
 	      return GLOB_NOSPACE;
 	    }
+
+	  new_gl_pathv
+	    = (char **) realloc (pglob->gl_pathv,
+				 (newcount + 1 + 1) * sizeof (char *));
+	  if (new_gl_pathv == NULL)
+	    goto nospace;
 	  pglob->gl_pathv = new_gl_pathv;
 
 	  if (flags & GLOB_MARK)
@@ -874,7 +888,7 @@ glob (pattern, flags, errfunc, pglob)
 	 appending the results to PGLOB.  */
       for (i = 0; i < dirs.gl_pathc; ++i)
 	{
-	  int old_pathc;
+	  size_t old_pathc;
 
 #ifdef	SHELL
 	  {
@@ -929,17 +943,22 @@ glob (pattern, flags, errfunc, pglob)
 	  /* No matches.  */
 	  if (flags & GLOB_NOCHECK)
 	    {
-	      int newcount = pglob->gl_pathc + pglob->gl_offs;
+	      size_t newcount = pglob->gl_pathc + pglob->gl_offs;
 	      char **new_gl_pathv;
 
-	      new_gl_pathv = (char **) realloc (pglob->gl_pathv,
-						(newcount + 2)
-						* sizeof (char *));
-	      if (new_gl_pathv == NULL)
+	      if (newcount > UINTPTR_MAX - 2
+		  || newcount + 2 > ~((size_t) 0) / sizeof (char *))
 		{
+		nospace2:
 		  globfree (&dirs);
 		  return GLOB_NOSPACE;
 		}
+
+	      new_gl_pathv = (char **) realloc (pglob->gl_pathv,
+						(newcount + 2)
+						* sizeof (char *));
+	      if (new_gl_pathv == NULL)
+		goto nospace2;
 	      pglob->gl_pathv = new_gl_pathv;
 
 	      pglob->gl_pathv[newcount] = __strdup (pattern);
@@ -968,7 +987,7 @@ glob (pattern, flags, errfunc, pglob)
     }
   else
     {
-      int old_pathc = pglob->gl_pathc;
+      size_t old_pathc = pglob->gl_pathc;
       int orig_flags = flags;
 
       if (meta & 2)
@@ -1442,6 +1461,13 @@ glob_in_dir (const char *pattern, const
     {
       result = 0;
 
+      if (pglob->gl_pathc > UINTPTR_MAX - pglob->gl_offs
+	  || pglob->gl_pathc + pglob->gl_offs > UINTPTR_MAX - nfound
+	  || pglob->gl_pathc + pglob->gl_offs + nfound > UINTPTR_MAX - 1
+	  || (pglob->gl_pathc + pglob->gl_offs + nfound + 1
+	      > UINTPTR_MAX / sizeof (char *)))
+	goto memory_error;
+
       char **new_gl_pathv;
       new_gl_pathv
 	= (char **) realloc (pglob->gl_pathv,
