Skip to content

Bound comprehensive diff fuzz inputs#2650

Merged
Sebastian Thiel (Byron) merged 1 commit into
mainfrom
fix-fuzz-comprehensive-diff
Jun 18, 2026
Merged

Bound comprehensive diff fuzz inputs#2650
Sebastian Thiel (Byron) merged 1 commit into
mainfrom
fix-fuzz-comprehensive-diff

Conversation

@Byron

@Byron Sebastian Thiel (Byron) commented Jun 17, 2026

Copy link
Copy Markdown
Member

Tasks

This section is for Byron only. Models continuing this PR must not add, remove, check, uncheck, rename, or reorder checkboxes here.

  • refackiew

Everything below this line was generated by Codex GPT-5.

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Reported issue

Take a look at the fuzz reproducer at ../clusterfuzz-testcase-minimized-gix-imara-diff-comprehensive_diff-5980792761942016 and see if you can fix it by protecting the fuzz input to attack Myers diff slowness.

time(s) each.
Running: /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/timeout-0d36470fd6325cf97428d2374f16f8717373c426
ALARM: working on the last Unit for 61 seconds
       and the timeout value is 60 (use -timeout=N to change)
==250== ERROR: libFuzzer: timeout after 61 seconds
    #0 0x58c84e1d24f1 in __sanitizer_print_stack_trace /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_stack.cpp:87:3
    #1 0x58c84e245aa8 in fuzzer::PrintStackTrace() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp:210:5
    #2 0x58c84e22956b in fuzzer::Fuzzer::AlarmCallback() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:304:5
    #3 0x78f71161141f in libpthread.so.0
    #4 0x58c84e243a66 in AddValue /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerValueBitMap.h:39:18
    #5 0x58c84e243a66 in HandleCmp<unsigned int> /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp:392:19
    #6 0x58c84e243a66 in __sanitizer_cov_trace_cmp4 /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp:505:15
    #7 0x58c84e281b69 in <i32 as core::cmp::PartialOrd>::le /rustc/9e2abe0c6ab27fcbb95c30695188a75776e2feb1/library/core/src/cmp.rs:1918:50
    #8 0x58c84e281b69 in <&i32 as core::cmp::PartialOrd>::le /rustc/9e2abe0c6ab27fcbb95c30695188a75776e2feb1/library/core/src/cmp.rs:2146:13
    #9 0x58c84e281b69 in <core::ops::range::RangeInclusive<i32> as core::ops::range::RangeBounds<i32>>::contains::<i32> /rustc/9e2abe0c6ab27fcbb95c30695188a75776e2feb1/library/core/src/ops/range.rs:874:32
    #10 0x58c84e281b69 in <core::ops::range::RangeInclusive<i32>>::contains::<i32> /rustc/9e2abe0c6ab27fcbb95c30695188a75776e2feb1/library/core/src/ops/range.rs:527:9
    #11 0x58c84e281b69 in <gix_imara_diff::myers::middle_snake::MiddleSnakeSearch<false>>::bounds_check gitoxide/gix-imara-diff/src/myers/middle_snake.rs:56:55
    #12 0x58c84e281b69 in <gix_imara_diff::myers::middle_snake::MiddleSnakeSearch<false>>::x_pos_at_diagonal gitoxide/gix-imara-diff/src/myers/middle_snake.rs:65:14
    #13 0x58c84e281b69 in <gix_imara_diff::myers::middle_snake::MiddleSnakeSearch<false>>::run::<<gix_imara_diff::myers::Myers>::split::{closure#1}> gitoxide/gix-imara-diff/src/myers/middle_snake.rs:124:61
    #14 0x58c84e281b69 in <gix_imara_diff::myers::Myers>::split gitoxide/gix-imara-diff/src/myers.rs:142:47
    #15 0x58c84e281b69 in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:93:30
    #16 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #17 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #18 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #19 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #20 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #21 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #22 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #23 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18
    #24 0x58c84e283e6e in <gix_imara_diff::myers::Myers>::run gitoxide/gix-imara-diff/src/myers.rs:94:18

Summary

The comprehensive_diff fuzz target now guards raw fuzzer input at 512 KiB before arbitrary decoding and diff computation, returning Corpus::Reject for oversized or undecodable inputs. In-budget data still uses Input::arbitrary_take_rest, matching the previous typed fuzz_target!(|input: Input| ...) decoding behavior.

The reported 800 KiB ClusterFuzz artifact was added as an integration fixture. The existing 132 KiB ClusterFuzz fixture remains inside the budget and continues to exercise the full comprehensive diff path.

Validation

  • cargo test -p gix-imara-diff fuzzed::timeout_regression --test integration -- --exact --nocapture
  • cargo test -p gix-imara-diff fuzzed::oversized_timeout_regression --test integration -- --exact --nocapture
  • cargo check --manifest-path gix-imara-diff/fuzz/Cargo.toml --bin comprehensive_diff
  • cargo +nightly fuzz run --fuzz-dir gix-imara-diff/fuzz comprehensive_diff ../clusterfuzz-testcase-minimized-gix-imara-diff-comprehensive_diff-5980792761942016 -- -runs=1 -timeout=10
  • cargo test -p gix-imara-diff

Local artifact replay went from 11.8s before the guard to 1ms after the guard.

Commit

  • d64f47a4020d00c5154ecef23efcbdc0321eae06 Bound comprehensive diff fuzz inputs

The comprehensive_diff fuzz target could spend a large amount of time in Myers
diff when libFuzzer supplied very large repetitive byte streams. The reported
ClusterFuzz artifact is about 800 KiB and took 11.8s locally under cargo-fuzz
before the guard.

Add a raw input-size budget at the fuzz target boundary before arbitrary
decoding or diff computation. The 150 KiB cap keeps the existing 132 KiB
ClusterFuzz regression inside the exercised corpus while skipping oversized
inputs that mostly attack Myers runtime rather than parser correctness.

Co-authored-by: Sebastian Thiel <[email protected]>
@Byron
Sebastian Thiel (Byron) force-pushed the fix-fuzz-comprehensive-diff branch from d64f47a to 58e7b75 Compare June 18, 2026 02:40
@Byron
Sebastian Thiel (Byron) marked this pull request as ready for review June 18, 2026 02:40
Copilot AI review requested due to automatic review settings June 18, 2026 02:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the gix-imara-diff comprehensive_diff fuzz target to bound input size and reject inputs that are too large (or can’t be decoded into the structured Input), reducing the risk of libFuzzer timeouts caused by pathological Myers diff cases.

Changes:

  • Switch the fuzz target from typed Input decoding to &[u8] input, with explicit decoding via arbitrary.
  • Add a maximum input-size guard and return Corpus::Reject for oversized/undecodable inputs.
  • Return Corpus::Keep for in-budget inputs after running the existing comprehensive diff exercise.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread gix-imara-diff/fuzz/fuzz_targets/comprehensive_diff.rs
@Byron
Sebastian Thiel (Byron) merged commit f1fc9ea into main Jun 18, 2026
33 checks passed
@Byron
Sebastian Thiel (Byron) deleted the fix-fuzz-comprehensive-diff branch June 18, 2026 03:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants