-
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_array_eq
Error Message:
Other error: Mismatch at step 3 at index 0
Expected scalar:
{: {: null, : "95 75 95 ff ff ff ff ff ff ff 0 3b 3b 3b"}, : null}
Actual scalar:
{: {: null, : "95 75 95 ff ff ff ff ff ff ff 0 3b 3b 3b"}, : {: null, : "95 75 95 ff ff ff ff ff ff ff 0 3b 3b 3b"}}
Expected tree:
root: vortex.struct({={=binary?, =binary?}?, ={=binary?, =binary?}?}?, len=11) nbytes=889 B (100.00%) [all_valid]
metadata: EmptyMetadata
: vortex.struct({=binary?, =binary?}?, len=11) nbytes=482 B (54.22%)
metadata: EmptyMetadata
validity: vortex.bool(bool, len=11) nbytes=2 B (0.41%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
: vortex.varbinview(binary?, len=11) nbytes=246 B (51.04%)
metadata: EmptyMetadata
buffer: buffer_0 host 68 B (align=1) (27.64%)
buffer: views host 176 B (align=16) (71.54%)
validity: vortex.bool(bool, len=11) nbytes=2 B (0.81%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
: vortex.varbinview(binary?, len=11) nbytes=234 B (48.55%)
metadata: EmptyMetadata
buffer: buffer_0 host 56 B (align=1) (23.93%)
buffer: views host 176 B (align=16) (75.21%)
validity: vortex.bool(bool, len=11) nbytes=2 B (0.85%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
: vortex.struct({=binary?, =binary?}?, len=11) nbytes=407 B (45.78%)
metadata: EmptyMetadata
validity: vortex.bool(bool, len=11) nbytes=2 B (0.49%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
: vortex.varbinview(binary?, len=11) nbytes=191 B (46.93%)
metadata: EmptyMetadata
buffer: buffer_0 host 13 B (align=1) (6.81%)
buffer: views host 176 B (align=16) (92.15%)
validity: vortex.bool(bool, len=11) nbytes=2 B (1.05%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
: vortex.varbinview(binary?, len=11) nbytes=214 B (52.58%)
metadata: EmptyMetadata
buffer: buffer_0 host 36 B (align=1) (16.82%)
buffer: views host 176 B (align=16) (82.24%)
validity: vortex.bool(bool, len=11) nbytes=2 B (0.93%) [nulls=0, min=false, max=true]
metadata: BoolMetadata { offset: 0 }
buffer: bits host 2 B (align=1) (100.00%)
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 an array equality assertion failure in the array_ops fuzz target (array_ops.rs:33) at step 3 of a fuzz action sequence. The mismatch occurs on a nested struct array with nullable binary fields: the expected scalar has a null value for the second struct field, but the actual scalar incorrectly populates that field with data copied from the first struct field instead of respecting the null. This strongly suggests a bug in how struct array operations (likely slice, filter, or take) propagate validity/nullness through nested struct children — when a parent struct field is null, the child data is being materialized rather than preserved as null. The fix should investigate the struct encoding's implementation of whichever array operation is triggered at step 3, ensuring that null parent entries produce null scalars rather than exposing stale or copied child data.
Summary
- Target:
array_ops - Crash File:
crash-847379185a914ddb7dbdc9b984ff5317fc053976 - Branch: develop
- Commit: a13c10a
- Crash Artifact: https://github.com/vortex-data/vortex/actions/runs/23084000115/artifacts/5923258017
Reproduce
cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-847379185a914ddb7dbdc9b984ff5317fc053976 -- -rss_limit_mb=0First-time setup: download and extract the crash artifact
-
Download the crash artifact:
- Direct download: https://github.com/vortex-data/vortex/actions/runs/23084000115/artifacts/5923258017
- Extract the zip file (
unzip)- The path should look like
/path/to/array_ops/crash-847379185a914ddb7dbdc9b984ff5317fc053976 - You can create a
./fuzz/artifactsdirectory that will be git-ignored in thevortexrepo - Full path would be
./fuzz/artifacts/array_ops/crash-847379185a914ddb7dbdc9b984ff5317fc053976
- The path should look like
-
Assuming you download the zipfile to
~/Downloads, and your working directory is the repository root:
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- Get a backtrace:
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-847379185a914ddb7dbdc9b984ff5317fc053976 -- -rss_limit_mb=0RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-847379185a914ddb7dbdc9b984ff5317fc053976 -- -rss_limit_mb=0Auto-created by fuzzing workflow