Check for overflows in expressions
authorUlrich Drepper <drepper@gmail.com>
Thu, 21 Jul 2011 02:53:58 +0000 (22:53 -0400)
committerUlrich Drepper <drepper@gmail.com>
Thu, 21 Jul 2011 02:53:58 +0000 (22:53 -0400)
Some passed in values might cause overflows in expressions.

ChangeLog
NEWS
posix/glob.c

index f47300f..a76483a 100644 (file)
--- 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 2dd7bea..0be2e91 100644 (file)
--- 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.
index 2cd5290..89c8775 100644 (file)
 
 #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,