Skip to content

Fuzzing Crash: VortexError in array_ops #6929

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: vortex-array/src/scalar_fn/fns/cast/mod.rs:120:execute

Error Message:

BtrBlocksCompressor compress should succeed in fuzz test:
  Other error: No CastKernel to cast canonical array vortex.bool from bool to fixed_size_list(binary)[2]
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: {closure#1}<alloc::sync::Arc<dyn vortex_array::array::DynArray, alloc::alloc::Global>, vortex_error::VortexError>
             at ./vortex-error/src/lib.rs:500:9
   4: unwrap_or_else<alloc::sync::Arc<dyn vortex_array::array::DynArray, alloc::alloc::Global>, vortex_error::VortexError, vortex_error::{impl#11}::vortex_expect::{closure_env#1}<alloc::sync::Arc<dyn vortex_array::array::DynArray, alloc::alloc::Global>, vortex_error::VortexError>>
             at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/core/src/result.rs:1622:23
   5: vortex_expect<alloc::sync::Arc<dyn vortex_array::array::DynArray, alloc::alloc::Global>, vortex_error::VortexError>
             at ./vortex-error/src/lib.rs:340:14
   6: compress_array
             at ./fuzz/src/array/mod.rs:539:14
   7: run_fuzz_action
             at ./fuzz/src/array/mod.rs:582:33
   8: __libfuzzer_sys_run
             at ./fuzz/fuzz_targets/array_ops.rs:30:11
   9: rust_fuzzer_test_input
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:363:60
  10: {closure#0}
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:62:9
  11: do_call<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
             at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:581:40
  12: __rust_try
  13: catch_unwind<i32, libfuzzer_sys::test_input_wrap::{closure_env#0}>
             at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panicking.rs:544:19
  14: catch_unwind<libfuzzer_sys::test_input_wrap::{closure_env#0}, i32>
             at /rustc/db3e99bbab28c6ca778b13222becdea54533d908/library/std/src/panic.rs:359:14
  15: test_input_wrap
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/src/lib.rs:60:22
  16: _ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerLoop.cpp:619:13
  17: _ZN6fuzzer10RunOneTestEPNS_6FuzzerEPKcm
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:335:6
  18: _ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerDriver.cpp:871:9
  19: main
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.12/libfuzzer/FuzzerMain.cpp:20:10
   ... (3 more frames truncated)

Root Cause Analysis

The crash is a VortexError panic in the cast module (vortex-array/src/scalar_fn/fns/cast/mod.rs:120) triggered during BtrBlocks compression in the fuzzer. The compressor attempts to cast a boolean array to fixed_size_list(binary)[2], but no CastKernel exists for this type conversion, causing the cast to fail and the unwrap (via vortex_expect) at fuzz/src/array/mod.rs:539 to panic. The root cause is that the BtrBlocks compressor does not check whether a valid cast path exists before attempting the conversion, or alternatively the cast registry is missing a kernel for bool-to-fixed_size_list(binary). The fix should either register the missing cast kernel, or have the compressor gracefully handle unsupported casts by skipping that compression path rather than panicking.

Summary

Reproduction

Details
  1. Download the crash artifact:

  2. Reproduce locally:

cargo +nightly fuzz run -D --sanitizer=none array_ops /path/to/crash_file -- -rss_limit_mb=0
  1. Get a backtrace:
RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none array_ops /path/to/crash_file -- -rss_limit_mb=0
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops /path/to/crash_file -- -rss_limit_mb=0

Workflow Example

Assuming you download the zipfile to ~/Downloads, and your working directory is the repository
root, you can follow these steps:

Details
# 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

You can now reproduce with:

cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-10f35db9521ae4f5acfe9fdfd23a8d6b2112f081 -- -rss_limit_mb=0

If you want a backtrace:

RUST_BACKTRACE=1 cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-10f35db9521ae4f5acfe9fdfd23a8d6b2112f081 -- -rss_limit_mb=0
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-10f35db9521ae4f5acfe9fdfd23a8d6b2112f081 -- -rss_limit_mb=0

Auto-created by fuzzing workflow

Metadata

Metadata

Assignees

Labels

bugA bug issuefuzzerIssues detected by the fuzzer

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions