about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS2
-rw-r--r--posix/glob.c42
3 files changed, 40 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f47300f92d..a76483ad2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 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.
+
 	[BZ #13007]
 	* sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): More complete
 	check for AVX enablement so that we don't crash with old kernels and
diff --git a/NEWS b/NEWS
index 2dd7bea2ef..0be2e91a8e 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.15
 
 * The following bugs are resolved with this release:
 
-  9696, 12868, 12874, 12885, 12907, 12922, 12935, 13007
+  9696, 12868, 12852, 12874, 12885, 12907, 12922, 12935, 13007
 
 * New program pldd to list loaded object of a process
   Implemented by Ulrich Drepper.
diff --git a/posix/glob.c b/posix/glob.c
index 2cd52904d5..89c8775109 100644
--- a/posix/glob.c
+++ b/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)
@@ -436,6 +442,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)
@@ -954,10 +964,8 @@ glob (pattern, flags, errfunc, pglob)
 	  int 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);
@@ -965,6 +973,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)
@@ -1104,14 +1118,19 @@ glob (pattern, flags, errfunc, pglob)
 	      int 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);
@@ -1636,6 +1655,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
     {
       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,