Fuzzing Crash Report
Analysis
Crash Location: fuzz/fuzz_targets/file_io.rs:100:__libfuzzer_sys_run
Error Message:
assertion `left == right` failed: Length was not preserved expected 6 actual 0.
left: 6
right: 0
Stack Trace
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:689:5
1: core::panicking::panic_fmt
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/panicking.rs:80:14
2: core::panicking::assert_failed_inner
3: core::panicking::assert_failed::<usize, usize>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/panicking.rs:394:5
4: __libfuzzer_sys_run
at ./fuzz/fuzz_targets/file_io.rs:100:5
5: rust_fuzzer_test_input
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:363:60
6: {closure#0}
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:62:9
7: do_call<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:581:40
8: __rust_try
9: catch_unwind<i32, libfuzzer_sys::test_input_wrap::{closure_env#0}>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:544:19
10: catch_unwind<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panic.rs:359:14
11: test_input_wrap
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:60:22
12: _ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerLoop.cpp:619:13
13: _ZN6fuzzer10RunOneTestEPNS_6FuzzerEPKcm
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:335:6
14: _ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:871:9
15: main
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerMain.cpp:20:10
16: <unknown>
17: __libc_start_main
18: _start
Root Cause Analysis
The crash is an assertion failure in the file_io fuzz target (fuzz/fuzz_targets/file_io.rs:100) where a round-trip through the Vortex file format loses all rows: the in-memory filtered/projected array has 6 elements but reading back from the written file with the same filter and projection returns 0 elements. The root cause is likely a bug in the scan-path filter pushdown logic (in vortex-scan or vortex-layout) where row group or chunk statistics are used to prune data during read — the pruning incorrectly eliminates all chunks that actually contain matching rows, producing an empty result. The fix should investigate how zone maps or per-chunk statistics interact with the fuzzed filter expression during scan, particularly for edge cases around nullable columns, boundary values, or compound filter predicates that may cause the pruning predicate to be overly aggressive.
Summary
Reproduce
cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0
Reproduction Steps
-
Download the crash artifact: https://github.com/vortex-data/vortex/actions/runs/26449115165/artifacts/7217603479
-
Assuming you download the zipfile to ~/Downloads, and your working directory is the repository root:
# Create the artifacts directory if you haven't already.
mkdir -p ./fuzz/artifacts
# Move the zipfile.
mv ~/Downloads/file_io-crash-artifacts.zip ./fuzz/artifacts/
# Unzip the zipfile.
unzip ./fuzz/artifacts/file_io-crash-artifacts.zip -d ./fuzz/artifacts/
# You can remove the zipfile now if you want to.
rm ./fuzz/artifacts/file_io-crash-artifacts.zip
- Reproduce the crash:
cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0
If you want a backtrace:
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0
Single command to get a backtrace
mkdir -p ./fuzz/artifacts
mv ~/Downloads/file_io-crash-artifacts.zip ./fuzz/artifacts/
unzip ./fuzz/artifacts/file_io-crash-artifacts.zip -d ./fuzz/artifacts/
rm ./fuzz/artifacts/file_io-crash-artifacts.zip
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0
Auto-created by fuzzing workflow
Fuzzing Crash Report
Analysis
Crash Location:
fuzz/fuzz_targets/file_io.rs:100:__libfuzzer_sys_runError Message:
Stack Trace
Root Cause Analysis
The crash is an assertion failure in the file_io fuzz target (fuzz/fuzz_targets/file_io.rs:100) where a round-trip through the Vortex file format loses all rows: the in-memory filtered/projected array has 6 elements but reading back from the written file with the same filter and projection returns 0 elements. The root cause is likely a bug in the scan-path filter pushdown logic (in vortex-scan or vortex-layout) where row group or chunk statistics are used to prune data during read — the pruning incorrectly eliminates all chunks that actually contain matching rows, producing an empty result. The fix should investigate how zone maps or per-chunk statistics interact with the fuzzed filter expression during scan, particularly for edge cases around nullable columns, boundary values, or compound filter predicates that may cause the pruning predicate to be overly aggressive.
Summary
file_iocrash-a15dea563e219f79970ff219d222bd34d7f3b0f9Reproduce
Reproduction Steps
Download the crash artifact: https://github.com/vortex-data/vortex/actions/runs/26449115165/artifacts/7217603479
Assuming you download the zipfile to
~/Downloads, and your working directory is the repository root:If you want a backtrace:
Single command to get a backtrace
mkdir -p ./fuzz/artifacts mv ~/Downloads/file_io-crash-artifacts.zip ./fuzz/artifacts/ unzip ./fuzz/artifacts/file_io-crash-artifacts.zip -d ./fuzz/artifacts/ rm ./fuzz/artifacts/file_io-crash-artifacts.zip RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none file_io ./fuzz/artifacts/file_io/crash-a15dea563e219f79970ff219d222bd34d7f3b0f9 -- -rss_limit_mb=0Auto-created by fuzzing workflow