about summary refs log tree commit diff
path: root/posix/glob.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-07-20 22:53:58 -0400
committerUlrich Drepper <drepper@gmail.com>2011-07-20 22:53:58 -0400
commit90bb2039e93c6b7e95531cf9a9dfc23bbb50f860 (patch)
tree9b0adacdb14f303defa48e7b727396d157ff4532 /posix/glob.c
parent5644ef5461b5d3ff266206d8ee70d4b575ea6658 (diff)
downloadglibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.tar.gz
glibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.tar.xz
glibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.zip
Check for overflows in expressions
Some passed in values might cause overflows in expressions.
Diffstat (limited to 'posix/glob.c')
-rw-r--r--posix/glob.c42
1 files changed, 34 insertions, 8 deletions
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,