From 90bb2039e93c6b7e95531cf9a9dfc23bbb50f860 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 20 Jul 2011 22:53:58 -0400 Subject: [PATCH] Check for overflows in expressions Some passed in values might cause overflows in expressions. --- ChangeLog | 5 +++++ NEWS | 2 +- posix/glob.c | 42 ++++++++++++++++++++++++++++++++++-------- 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 + [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 +#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; + 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) - { - globfree (&dirs); - return GLOB_NOSPACE; - } + 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,