diff options
author | Florian Weimer <fweimer@redhat.com> | 2015-03-23 16:12:38 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2015-03-23 16:12:38 +0100 |
commit | 2b028564f14d20cdda0c00d8ba100695b40501f5 (patch) | |
tree | 46699eeec32449e0894c69d8d39c30c39e6d1c63 | |
parent | 59261ad3eb345e0d7b9f5c73e1a09d046991cea5 (diff) | |
download | glibc-2b028564f14d20cdda0c00d8ba100695b40501f5.tar.gz glibc-2b028564f14d20cdda0c00d8ba100695b40501f5.tar.xz glibc-2b028564f14d20cdda0c00d8ba100695b40501f5.zip |
Avoid SIGFPE in wordexp [BZ #18100]
Check for a zero divisor and integer overflow before performing division in arithmetic expansion.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | manual/pattern.texi | 3 | ||||
-rw-r--r-- | posix/wordexp-test.c | 40 | ||||
-rw-r--r-- | posix/wordexp.c | 4 |
5 files changed, 58 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog index 2a9b972ad0..c1b91061ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2015-03-23 Florian Weimer <fweimer@redhat.com> + + [BZ #18100] + * posix/wordexp.c (eval_expr_multdiv): Check for division by zero + and integer overflow. + * posix/wordexp-test.c (test_case): Add divide-by-zero test. + (main): Add integer overflow tests. + * manual/pattern.texi (Calling Wordexp): Document additional use + for WRDE_SYNTAX. + 2015-03-23 Alan Modra <amodra@gmail.com> * config.h.in: Remove HAVE_ASM_PPC_REL16. diff --git a/NEWS b/NEWS index 7c8a557727..aec1957abe 100644 --- a/NEWS +++ b/NEWS @@ -14,8 +14,8 @@ Version 2.22 17621, 17628, 17631, 17711, 17776, 17779, 17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967, 17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029, 18030, 18032, 18036, 18038, - 18039, 18042, 18043, 18046, 18047, 18068, 18080, 18093, 18104, 18110, - 18111, 18128, 18138. + 18039, 18042, 18043, 18046, 18047, 18068, 18080, 18093, 18100, 18104, + 18110, 18111, 18128, 18138. * Character encoding and ctype tables were updated to Unicode 7.0.0, using new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red diff --git a/manual/pattern.texi b/manual/pattern.texi index da848c340b..d1b9275cf9 100644 --- a/manual/pattern.texi +++ b/manual/pattern.texi @@ -2006,7 +2006,8 @@ allocate room for. @comment POSIX.2 @item WRDE_SYNTAX There was a syntax error in the input string. For example, an unmatched -quoting character is a syntax error. +quoting character is a syntax error. This error code is also used to +signal division by zero and overflow in arithmetic expansion. @end table @end deftypefun diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c index 0a353a45c3..73f1b7d3ca 100644 --- a/posix/wordexp-test.c +++ b/posix/wordexp-test.c @@ -237,6 +237,7 @@ struct test_case_struct { WRDE_SYNTAX, NULL, "`\\", 0, 0, { NULL, }, IFS }, /* BZ 18042 */ { WRDE_SYNTAX, NULL, "${", 0, 0, { NULL, }, IFS }, /* BZ 18043 */ { WRDE_SYNTAX, NULL, "L${a:", 0, 0, { NULL, }, IFS }, /* BZ 18043#c4 */ + { WRDE_SYNTAX, NULL, "$[1/0]", WRDE_NOCMD, 0, {NULL, }, IFS }, /* BZ 18100 */ { -1, NULL, NULL, 0, 0, { NULL, }, IFS }, }; @@ -362,6 +363,45 @@ main (int argc, char *argv[]) ++fail; } + /* Integer overflow in division. */ + { + static const char *const numbers[] = { + "0", + "1", + "65536", + "2147483648", + "4294967296" + "9223372036854775808", + "18446744073709551616", + "170141183460469231731687303715884105728", + "340282366920938463463374607431768211456", + NULL + }; + + for (const char *const *num = numbers; *num; ++num) + { + wordexp_t p; + char pattern[256]; + snprintf (pattern, sizeof (pattern), "$[(-%s)/(-1)]", *num); + int ret = wordexp (pattern, &p, WRDE_NOCMD); + if (ret == 0) + { + if (p.we_wordc != 1 || strcmp (p.we_wordv[0], *num) != 0) + { + printf ("Integer overflow for \"%s\" failed", pattern); + ++fail; + } + wordfree (&p); + } + else if (ret != WRDE_SYNTAX) + { + printf ("Integer overflow for \"%s\" failed with %d", + pattern, ret); + ++fail; + } + } + } + puts ("tests completed, now cleaning up"); /* Clean up */ diff --git a/posix/wordexp.c b/posix/wordexp.c index f6062d58c8..e711d43355 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -617,6 +617,10 @@ eval_expr_multdiv (char **expr, long int *result) if (eval_expr_val (expr, &arg) != 0) return WRDE_SYNTAX; + /* Division by zero or integer overflow. */ + if (arg == 0 || (arg == -1 && *result == LONG_MIN)) + return WRDE_SYNTAX; + *result /= arg; } else break; |