]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Check for overflows in expressions
authorUlrich Drepper <drepper@gmail.com>
Thu, 21 Jul 2011 02:53:58 +0000 (22:53 -0400)
committerAndreas Schwab <schwab@redhat.com>
Thu, 21 Jul 2011 12:49:27 +0000 (14:49 +0200)
Some passed in values might cause overflows in expressions.
(cherry picked from commit 90bb2039e93c6b7e95531cf9a9dfc23bbb50f860)

ChangeLog
posix/glob.c

index 36ddde77f4bfae9a873a1b7a97b7328ba0c922d3..515f22c0462a3ab2beae886b0b0b736f79029e25 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +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.
+
 2011-07-20  Ulrich Drepper  <drepper@gmail.com>
 
        * sysdeps/x86_64/bits/link.h (La_x86_64_ymm): Force 16-byte alignment.
index 2cd52904d512b43917f0726499d610d1f36ab9ed..89c87751093012a69dc45844d40d8d55dc4dec34 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,