Regression test for CVE-2026-53910, fixed in commits 73ed7ce85cc7
("diff3: check for integer overflows when reading line numbers from
diff") and 9ff04d5b8474 ("diff3: prevent overflow in line offsets").readnum accepted line numbers larger than LIN_MAX, silently wrapping them to a bogus value instead of rejecting the input. Drive diff3 with a stub --diff-program that emits a control line with an out-of-range line number and check that diff3 fails cleanly rather than acting on the wrapped value. * tests/CVE-2026-53910-test: New test. * tests/Makefile.am (TESTS): Add it. AI-Generated: Uses Kiro CLI Signed-off-by: Pratik Farkase <[email protected]> --- tests/CVE-2026-53910-test | 46 +++++++++++++++++++++++++++++++++++++++ tests/Makefile.am | 1 + 2 files changed, 47 insertions(+) create mode 100755 tests/CVE-2026-53910-test diff --git a/tests/CVE-2026-53910-test b/tests/CVE-2026-53910-test new file mode 100755 index 0000000..d137425 --- /dev/null +++ b/tests/CVE-2026-53910-test @@ -0,0 +1,46 @@ +#!/bin/sh +# Regression test for an integer overflow in diff3's readnum (CVE-2026-53910). +# +# This test was generated with the assistance of an AI tool. +# +# diff3 parses line numbers out of the diff program's output. Before the +# fix, readnum accumulated digits with "num = c - '0' + num * 10" and never +# checked for overflow, so a line number larger than LIN_MAX silently wrapped +# to a bogus in-range value and diff3 proceeded to use it. After the fix, +# readnum rejects an out-of-range line number and diff3 fails cleanly with a +# "diff failed" diagnostic instead of emitting garbage. +# +# We drive diff3 with a stub --diff-program that prints a normal-diff control +# line whose first line number (20 nines) exceeds LIN_MAX on any current +# platform, so the behaviour does not depend on the real diff or on the input +# files having an impractically large number of lines. + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +# A stand-in "diff" that emits a control line with an overflowing line number. +cat <<'EOF' > fake-diff || framework_failure_ +#!/bin/sh +echo '99999999999999999999c1' +echo '< a' +echo '---' +echo '> b' +EOF +chmod +x fake-diff || framework_failure_ + +echo a > a || framework_failure_ +echo b > b || framework_failure_ +echo c > c || framework_failure_ + +fail=0 + +# With the overflow fix in place diff3 must reject the bogus line number. +# Prior to the fix diff3 silently wrapped it (e.g. to 7766279631452241919) +# and exited 0, so "returns_ 2" fails on a vulnerable diff3. +returns_ 2 diff3 --diff-program="./fake-diff" a b c > out 2> err || fail=1 + +# The diagnostic must name the offending control line, and the wrapped +# value must never appear in either stream. +grep 'diff failed' err || fail=1 +grep '77662796' out err && fail=1 + +Exit $fail diff --git a/tests/Makefile.am b/tests/Makefile.am index 47449fc..bd88fe4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -9,6 +9,7 @@ TESTS = \ cmp \ colliding-file-names \ diff3 \ + CVE-2026-53910-test \ empty-file \ excess-slash \ expand-tabs \ -- 2.43.0
