Skip to content

Fuzzing Crash: VortexError in array_ops #6933

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: vortex-array/src/dtype/dtype_impl.rs:381:as_struct_fields

Error Message:

Other error: DType is not a Struct
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: as_struct_fields
             at ./vortex-array/src/dtype/dtype_impl.rs:381:9
   4: reduce_parent
             at ./vortex-array/src/arrays/struct_/compute/rules.rs:54:44
   5: reduce_parent<vortex_array::arrays::struct_::vtable::Struct, vortex_array::arrays::struct_::compute::rules::StructCastPushDownRule>
             at ./vortex-array/src/optimizer/rules.rs:86:19
   6: evaluate<vortex_array::arrays::struct_::vtable::Struct>
             at ./vortex-array/src/optimizer/rules.rs:149:41
   7: reduce_parent
             at ./vortex-array/src/arrays/struct_/vtable/mod.rs:219:22
   8: reduce_parent<vortex_array::arrays::struct_::vtable::Struct>
             at ./vortex-array/src/vtable/dyn_.rs:129:29
   9: try_optimize
             at ./vortex-array/src/optimizer/mod.rs:51:53
  10: optimize
             at ./vortex-array/src/optimizer/mod.rs:22:12
  11: cast
             at ./vortex-array/src/builtins.rs:153:14
  12: cast
             at ./vortex-array/src/arrays/chunked/compute/cast.rs:18:36
  13: reduce_parent<vortex_array::arrays::chunked::vtable::Chunked>
             at ./vortex-array/src/scalar_fn/fns/cast/kernel.rs:63:9
  14: reduce_parent<vortex_array::arrays::chunked::vtable::Chunked, vortex_array::scalar_fn::fns::cast::kernel::CastReduceAdaptor<vortex_array::arrays::chunked::vtable::Chunked>>
             at ./vortex-array/src/optimizer/rules.rs:86:19
  15: evaluate<vortex_array::arrays::chunked::vtable::Chunked>
             at ./vortex-array/src/optimizer/rules.rs:149:41
  16: reduce_parent
             at ./vortex-array/src/arrays/chunked/vtable/mod.rs:260:22
  17: reduce_parent<vortex_array::arrays::chunked::vtable::Chunked>
             at ./vortex-array/src/vtable/dyn_.rs:129:29
  18: try_optimize
             at ./vortex-array/src/optimizer/mod.rs:51:53
  19: optimize
   ... (119 more frames truncated)

Root Cause Analysis

The crash is a panic in DType::as_struct_fields() (dtype_impl.rs:381) which is called from StructCastPushDownRule::reduce_parent (rules.rs:54) when the cast target DType is not a Struct. The rule unconditionally calls parent.options.as_struct_fields() on the cast target type without first checking that the target DType is actually a Struct variant, so when a chunked array containing struct chunks is cast to a non-struct DType, the optimizer pushes down into StructCastPushDownRule which panics. The fix should guard the as_struct_fields() call in StructCastPushDownRule::reduce_parent with a check that parent.options is DType::Struct, returning Ok(None) to skip the rule when it is not.

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-043d4a2f3897d6394204ba597587f897d4ff28c7 -- -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-043d4a2f3897d6394204ba597587f897d4ff28c7 -- -rss_limit_mb=0
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops ./fuzz/artifacts/array_ops/crash-043d4a2f3897d6394204ba597587f897d4ff28c7 -- -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