CVE-2023-50268: Out-of-bounds Write (CWE-787)
value: jq is a command-line JSON processor. Version 1.7 is vulnerable to stack-based buffer overflow in builds using decNumber. Version 1.7.1 contains a patch for this issue.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2023-12-13T21:15Z
Repository: https://github.com/jqlang/jq
Language: Other
Files changed: NEWS.md, src/jv.c, tests/shtest
Commit date: 2023-12-13 20:17:17 +0100
Commit message: Merge pull request from GHSA-7hmr-442f-qc8j

The unit allocated for decNumberCompare was accidentally removed by
commit 680baeffeb7983e7570b5e68db07fe47f94db8c7 (PR #2804)

This caused a stack overflow when comparing a nan with a payload of 1000
or more.

This bug was found by OSS-fuzz.
Ref: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64771
Fixes GHSA-7hmr-442f-qc8j

It also fixes 1e999999999 > 1e-1147483646   triggering UBSAN errors
Fixes #2968
Diff: diff --git a/NEWS.md b/NEWS.md
index fffdbd9..913be89 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,11 +1,11 @@
 # 1.7.1
 
 ## Security
 
 - CVE-2023-50246: ....
-- CVE-2023-50268: ....
+- CVE-2023-50268: fix stack-buffer-overflow if comparing nan with payload
 
 ## CLI changes
 
 - Make the default background color more suitable for bright backgrounds. @mjarosie @taoky @nicowilliams @itchyny #2904
 - Allow passing the inline jq script after `--`. @emanuele6 #2919
diff --git a/src/jv.c b/src/jv.c
index 4031dc6..6ca1e1d 100644
--- a/src/jv.c
+++ b/src/jv.c
@@ -738,19 +738,23 @@ int jvp_number_cmp(jv a, jv b) {
   assert(JVP_HAS_KIND(a, JV_KIND_NUMBER));
   assert(JVP_HAS_KIND(b, JV_KIND_NUMBER));
 
 #ifdef USE_DECNUM
   if (JVP_HAS_FLAGS(a, JVP_FLAGS_NUMBER_LITERAL) && JVP_HAS_FLAGS(b, JVP_FLAGS_NUMBER_LITERAL)) {
-    decNumber res;
-    decNumberCompare(&res,
+    struct {
+      decNumber number;
+      decNumberUnit units[1];
+    } res;
+
+    decNumberCompare(&res.number,
                      jvp_dec_number_ptr(a),
                      jvp_dec_number_ptr(b),
                      DEC_CONTEXT()
                      );
-    if (decNumberIsZero(&res)) {
+    if (decNumberIsZero(&res.number)) {
       return 0;
-    } else if (decNumberIsNegative(&res)) {
+    } else if (decNumberIsNegative(&res.number)) {
       return -1;
     } else {
       return 1;
     }
   }
diff --git a/tests/shtest b/tests/shtest
index 469ea1d..a426c79 100755
--- a/tests/shtest
+++ b/tests/shtest
@@ -592,10 +592,15 @@ cr=$(printf \\r)
 if ! x=$($JQ -n "1 # foo$cr + 2") || [ "$x" != 1 ]; then
   echo 'regression: carriage return terminates comment'
   exit 1
 fi
 
+# CVE-2023-50268: No stack overflow comparing a nan with a large payload
+$VALGRIND $Q $JQ '1 != .' <<\EOF >/dev/null
+Nan4000
+EOF
+
 # Allow passing the inline jq script before -- #2919
 if ! r=$($JQ --args -rn -- '$ARGS.positional[0]' bar) || [ "$r" != bar ]; then
     echo "passing the inline script after -- didn't work"
     exit 1
 fi

Vulnerable code: - CVE-2023-50268: ....
    decNumber res;
    decNumberCompare(&res,
    if (decNumberIsZero(&res)) {
    } else if (decNumberIsNegative(&res)) {
Fixed code: - CVE-2023-50268: fix stack-buffer-overflow if comparing nan with payload
    struct {
      decNumber number;
      decNumberUnit units[1];
    } res;

    decNumberCompare(&res.number,
    if (decNumberIsZero(&res.number)) {
    } else if (decNumberIsNegative(&res.number)) {
# CVE-2023-50268: No stack overflow comparing a nan with a large payload
$VALGRIND $Q $JQ '1 != .' <<\EOF >/dev/null
Nan4000
EOF