diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-07-20 22:53:58 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-07-20 22:53:58 -0400 |
commit | 90bb2039e93c6b7e95531cf9a9dfc23bbb50f860 (patch) | |
tree | 9b0adacdb14f303defa48e7b727396d157ff4532 /posix/glob.c | |
parent | 5644ef5461b5d3ff266206d8ee70d4b575ea6658 (diff) | |
download | glibc-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.c | 42 |
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, |