]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Avoid SIGFPE in wordexp [BZ #18100]
authorFlorian Weimer <fweimer@redhat.com>
Mon, 23 Mar 2015 15:12:38 +0000 (16:12 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Mon, 23 Mar 2015 15:12:38 +0000 (16:12 +0100)
Check for a zero divisor and integer overflow before performing
division in arithmetic expansion.

ChangeLog
NEWS
manual/pattern.texi
posix/wordexp-test.c
posix/wordexp.c

index 2a9b972ad05d838fd4aba329c2e048dd51568381..c1b91061ba73f96bb8271df677046cc85bacd39e 100644 (file)
--- 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 7c8a557727d8e0599dd4aceb11c267c51987bf86..aec1957abe438f025fdb4d58392567ae7166de8c 100644 (file)
--- 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
index da848c340b01587621a3e0551d230252707ed744..d1b9275cf9c727bec19ec648c961d255e4df2d18 100644 (file)
@@ -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
 
index 0a353a45c3cb7ef6756ceaa6ae261d87c13bd2ec..73f1b7d3caba89c8efd11c6550983ea34108c228 100644 (file)
@@ -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 */
index f6062d58c815cd10bff26e8afa7129b7d04189f4..e711d4335521fbb24076386d39862f0842c1a502 100644 (file)
@@ -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;