Skip to content

Commit

Permalink
Avoid SIGFPE in wordexp [BZ #18100]
Browse files Browse the repository at this point in the history
Check for a zero divisor and integer overflow before performing
division in arithmetic expansion.
  • Loading branch information
Florian Weimer committed Mar 23, 2015
1 parent 59261ad commit 2b02856
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 3 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 2 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion manual/pattern.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
40 changes: 40 additions & 0 deletions posix/wordexp-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};
Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 4 additions & 0 deletions posix/wordexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 2b02856

Please sign in to comment.