-
Notifications
You must be signed in to change notification settings - Fork 145
Fuzzing Crash: VortexError in array_ops #7200
Description
Fuzzing Crash Report
Analysis
Crash Location: vortex-array/src/patches.rs:680:slice
Error Message:
attempt to subtract with overflow
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::panic_const::panic_const_sub_overflow
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/panicking.rs:175:17
3: {closure#1}
at ./vortex-array/src/patches.rs:680:20
4: map<&alloc::sync::Arc<dyn vortex_array::array::DynArray, alloc::alloc::Global>, core::result::Result<usize, vortex_error::VortexError>, vortex_array::patches::{impl#1}::slice::{closure_env#1}>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/option.rs:1165:29
5: slice
at ./vortex-array/src/patches.rs:674:14
6: {closure#0}
at ./encodings/fastlanes/src/bitpacking/compute/slice.rs:35:32
7: map<&vortex_array::patches::Patches, core::result::Result<core::option::Option<vortex_array::patches::Patches>, vortex_error::VortexError>, vortex_fastlanes::bitpacking::compute::slice::{impl#0}::slice::{closure_env#0}>
at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/option.rs:1165:29
8: slice
at ./encodings/fastlanes/src/bitpacking/compute/slice.rs:35:22
9: reduce_parent<vortex_fastlanes::bitpacking::vtable::BitPacked>
at ./vortex-array/src/arrays/slice/mod.rs:94:9
10: reduce_parent<vortex_fastlanes::bitpacking::vtable::BitPacked, vortex_array::arrays::slice::SliceReduceAdaptor<vortex_fastlanes::bitpacking::vtable::BitPacked>>
at ./vortex-array/src/optimizer/rules.rs:113:19
11: evaluate<vortex_fastlanes::bitpacking::vtable::BitPacked>
at ./vortex-array/src/optimizer/rules.rs:180:41
12: reduce_parent
at ./encodings/fastlanes/src/bitpacking/vtable/mod.rs:172:15
13: reduce_parent<vortex_fastlanes::bitpacking::vtable::BitPacked>
at ./vortex-array/src/vtable/dyn_.rs:146:29
14: try_optimize
at ./vortex-array/src/optimizer/mod.rs:58:53
15: optimize
at ./vortex-array/src/optimizer/mod.rs:29:12
16: slice<vortex_fastlanes::bitpacking::vtable::BitPacked>
at ./vortex-array/src/array/mod.rs:454:14
17: slice
at ./vortex-array/src/arrays/dict/compute/slice.rs:19:41
18: reduce_parent<vortex_array::arrays::dict::vtable::Dict>
at ./vortex-array/src/arrays/slice/mod.rs:94:9
19: reduce_parent<vortex_array::arrays::dict::vtable::Dict, vortex_array::arrays::slice::SliceReduceAdaptor<vortex_array::arrays::dict::vtable::Dict>>
... (87 more frames truncated)
Root Cause Analysis
The crash is a subtraction overflow panic at patches.rs:680, where slice_start_idx is less than base_offset during a Patches::slice operation. This occurs when slicing a BitPacked array (via a Dict encoding) triggers the optimizer's slice reduction, and the chunk_offsets' first element (base_offset) ends up larger than the computed slice_start_idx, likely due to an off-by-one in chunk index calculation or an edge case where the slice range doesn't align with chunk boundaries. The fix should add a bounds check or use saturating_sub, or more precisely ensure that the chunk_start_idx calculation on line 666 correctly identifies the chunk containing slice_start_idx so that the base_offset retrieved from chunk_offsets is always <= slice_start_idx.
Summary
- Target:
array_ops - Crash File:
crash-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 - Branch: develop
- Commit: d0ed3fc
- Crash Artifact: https://github.com/vortex-data/vortex/actions/runs/23695323317/artifacts/6161706342
Reproduce
cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 -- -rss_limit_mb=0Reproduction Steps
-
Download the crash artifact: https://github.com/vortex-data/vortex/actions/runs/23695323317/artifacts/6161706342
-
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-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 -- -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-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 -- -rss_limit_mb=0RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 -- -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-78a4bdcaa9ca8a1ae1d02c2b6dfa71c64b2319f3 -- -rss_limit_mb=0Auto-created by fuzzing workflow