From: Ulrich Drepper Date: Thu, 21 Jul 2011 02:53:58 +0000 (-0400) Subject: Check for overflows in expressions X-Git-Tag: glibc-2.14.1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63072fc6170f06657800a536c084db5d6e45e80f;p=thirdparty%2Fglibc.git Check for overflows in expressions Some passed in values might cause overflows in expressions. (cherry picked from commit 90bb2039e93c6b7e95531cf9a9dfc23bbb50f860) --- diff --git a/ChangeLog b/ChangeLog index 36ddde77f4b..515f22c0462 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-07-20 Ulrich Drepper + + [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 * sysdeps/x86_64/bits/link.h (La_x86_64_ymm): Force 16-byte alignment. diff --git a/posix/glob.c b/posix/glob.c index 2cd52904d51..89c87751093 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -46,6 +46,12 @@ #include +#if defined HAVE_STDINT_H || defined _LIBC +# include +#elif !defined UINTPTR_MAX +# define UINTPTR_MAX (~((size_t) 0)) +#endif + #include #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,