[ovs-dev] [PATCH] json: Avoid signed integer overflow in parsing exponents.

Ben Pfaff blp at ovn.org
Mon Jun 25 18:23:36 UTC 2018


This can't cause a crash and doesn't seem relevant to normal operation.

Reported-at: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9044
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 lib/json.c    | 13 +++++++++++--
 tests/json.at | 14 +++++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/lib/json.c b/lib/json.c
index 99a68a3d9eac..32d25003b810 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -718,16 +718,21 @@ json_lex_number(struct json_parser *p)
         exponent = 0;
         do {
             if (exponent >= INT_MAX / 10) {
-                json_error(p, "exponent outside valid range");
-                return;
+                goto bad_exponent;
             }
             exponent = exponent * 10 + (*cp - '0');
             cp++;
         } while (isdigit((unsigned char) *cp));
 
         if (negative_exponent) {
+            if (pow10 < INT_MIN + exponent) {
+                goto bad_exponent;
+            }
             pow10 -= exponent;
         } else {
+            if (pow10 > INT_MAX - exponent) {
+                goto bad_exponent;
+            }
             pow10 += exponent;
         }
     }
@@ -777,6 +782,10 @@ json_lex_number(struct json_parser *p)
         token.real = 0;
     }
     json_parser_input(p, &token);
+    return;
+
+bad_exponent:
+    json_error(p, "exponent outside valid range");
 }
 
 static const char *
diff --git a/tests/json.at b/tests/json.at
index 325ac94354b3..3c9e7cdafda1 100644
--- a/tests/json.at
+++ b/tests/json.at
@@ -279,10 +279,22 @@ JSON_CHECK_NEGATIVE(
   [1e9999 is too big],
   [[[1e9999]]],
   [error: number outside valid range])
-JSON_CHECK_NEGATIVE(
+JSON_CHECK_NEGATIVE_C(
   [exponent bigger than INT_MAX],
   [[[1e9999999999999999999]]],
   [error: exponent outside valid range])
+JSON_CHECK_NEGATIVE_C(
+  [exponent smaller than INT_MIN],
+  [[[1e-9999999999999999999]]],
+  [error: exponent outside valid range])
+JSON_CHECK_NEGATIVE_C(
+  [accumulated exponent bigger than INT_MAX],
+  [[[340282366920938463461761716499e2147483647]]],
+  [error: exponent outside valid range])
+JSON_CHECK_NEGATIVE_C(
+  [accumulated exponent smaller than INT_MIN],
+  [[[0.340282366920938463461761716499e-2147483648]]],
+  [error: exponent outside valid range])
 JSON_CHECK_NEGATIVE(
   [decimal point must be followed by digit],
   [[[1.]]],
-- 
2.16.1



More information about the dev mailing list