-
Notifications
You must be signed in to change notification settings - Fork 142
Description
Fuzzing Crash Report
Analysis
Crash Location: fuzz/fuzz_targets/array_ops.rs:33:assert_min_max_eq
Error Message:
Other error: MinMax mismatch: expected Some(MinMaxResult { min: Scalar { dtype: Bool(NonNullable), value: Some(Bool(true)) }, max: Scalar { dtype: Bool(NonNullable), value: Some(Bool(true)) } }) got Some(MinMaxResult { min: Scalar { dtype: Bool(NonNullable), value: Some(Bool(false)) }, max: Scalar { dtype: Bool(NonNullable), value: Some(Bool(true)) } }) in step 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: panic_display<vortex_error::VortexError>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/panicking.rs:259:5
3: __libfuzzer_sys_run
at ./fuzz/fuzz_targets/array_ops.rs:33:19
4: rust_fuzzer_test_input
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:363:60
5: {closure#0}
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:62:9
6: do_call<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:581:40
7: __rust_try
8: catch_unwind<i32, libfuzzer_sys::test_input_wrap::{closure_env#0}>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:544:19
9: catch_unwind<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panic.rs:359:14
10: test_input_wrap
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:60:22
11: _ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerLoop.cpp:619:13
12: _ZN6fuzzer10RunOneTestEPNS_6FuzzerEPKcm
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:335:6
13: _ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:871:9
14: main
at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerMain.cpp:20:10
15: <unknown>
16: __libc_start_main
17: _start
Root Cause Analysis
The crash is a MinMax mismatch in the array_ops fuzzer at fuzz/fuzz_targets/array_ops.rs:33, where a Bool array's min/max computed from an encoded form returns min=false, max=true, but the expected result from the canonical form is min=true, max=true. This indicates that all valid (non-null) boolean values are true, yet the encoded array's min/max computation incorrectly includes false values from null positions. The root cause is likely in accumulate_bool (vortex-array/src/aggregate_fn/fns/min_max/bool.rs), where the "all true" fast-path check at line 34 (slice.0 == 0 && slice.1 == array.len()) fails when null positions create gaps in the true_non_null bit buffer, and the fallback validity check at lines 44-58 only runs for Mask::Values but not for Mask::AllTrue, causing arrays with certain encodings that decompress with false bits at null positions to incorrectly fall through to the mixed true/false result.
Summary
- Target:
array_ops - Crash File:
crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 - Branch: develop
- Commit: 43ae2dc
- Crash Artifact: https://github.com/vortex-data/vortex/actions/runs/23323688971/artifacts/6018127024
Reproduce
cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 -- -rss_limit_mb=0Reproduction Steps
-
Download the crash artifact: https://github.com/vortex-data/vortex/actions/runs/23323688971/artifacts/6018127024
-
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/array_ops-crash-artifacts.zip ./fuzz/artifacts/
# Unzip the zipfile.
unzip ./fuzz/artifacts/array_ops-crash-artifacts.zip -d ./fuzz/artifacts/
# You can remove the zipfile now if you want to.
rm ./fuzz/artifacts/array_ops-crash-artifacts.zip- Reproduce the crash:
cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 -- -rss_limit_mb=0If you want a backtrace:
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 -- -rss_limit_mb=0RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 -- -rss_limit_mb=0Single command to get a backtrace
mkdir -p ./fuzz/artifacts
mv ~/Downloads/array_ops-crash-artifacts.zip ./fuzz/artifacts/
unzip ./fuzz/artifacts/array_ops-crash-artifacts.zip -d ./fuzz/artifacts/
rm ./fuzz/artifacts/array_ops-crash-artifacts.zip
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-b1ebde7ebe4eff50d2b1487f67cb0a9053762bb9 -- -rss_limit_mb=0Auto-created by fuzzing workflow