aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-07-20 22:53:58 -0400
committerUlrich Drepper <drepper@gmail.com>2011-07-20 22:53:58 -0400
commit90bb2039e93c6b7e95531cf9a9dfc23bbb50f860 (patch)
tree9b0adacdb14f303defa48e7b727396d157ff4532
parent5644ef5461b5d3ff266206d8ee70d4b575ea6658 (diff)
downloadglibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.tar
glibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.tar.gz
glibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.tar.bz2
glibc-90bb2039e93c6b7e95531cf9a9dfc23bbb50f860.zip
Check for overflows in expressions
Some passed in values might cause overflows in expressions.
-rw-r--r--ChangeLog5
-rw-r--r--NEWS2
-rw-r--r--posix/glob.c42
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 <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 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 <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,