Skip to content

Fuzzing Crash: Missing cast kernel from bool to list(bool) during mask operation #5865

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: vortex-array/src/compute/cast.rs:80 in the invoke function

Error Message:

mask operation should succeed in fuzz test:
  No compute kernel to cast array vortex.bool with dtype bool? to list(bool?)

Stack Trace:

   3: invoke
             at ./vortex-array/src/compute/cast.rs:80:13
   4: invoke
             at ./vortex-array/src/compute/mod.rs:149:34
   5: cast
             at ./vortex-array/src/compute/cast.rs:39:10
   6: cast
             at ./vortex-array/src/arrays/struct_/compute/cast.rs:53:38
   7: invoke<vortex_array::arrays::struct_::vtable::StructVTable>
             at ./vortex-array/src/compute/cast.rs:155:12
   8: invoke
             at ./vortex-array/src/compute/cast.rs:63:42
   9: invoke
             at ./vortex-array/src/compute/mod.rs:149:34
  10: cast
             at ./vortex-array/src/compute/cast.rs:39:10
  11: invoke
             at ./vortex-array/src/compute/mask.rs:116:23
  12: invoke
             at ./vortex-array/src/compute/mod.rs:149:34
  13: mask
             at ./vortex-array/src/compute/mask.rs:70:10
  14: run_fuzz_action
             at ./fuzz/src/array/mod.rs:613:33

Root Cause: The fuzzer discovered a missing cast implementation. During a mask operation on a StructArray, the code needs to cast a BoolArray field from bool? (nullable bool) to list(bool?) (list of nullable bools). However, no cast kernel exists for this conversion.

Looking at the code path:

  1. Mask operation is called on a StructArray (fuzz/src/array/mod.rs:613)
  2. Mask operation tries to cast the array to nullable (vortex-array/src/compute/mask.rs:116)
  3. StructArray cast attempts to cast each field to the target type (vortex-array/src/arrays/struct_/compute/cast.rs:53)
  4. One field needs to be cast from bool? to list(bool?), but this cast is not supported
  5. The array is canonical (BoolArray), so it fails with "No compute kernel to cast" error (vortex-array/src/compute/cast.rs:80-85)

Array Structure:

  • StructArray with 2 fields (both named "")
  • Field 0: BoolArray with dtype bool?
  • Field 1: ChunkedArray containing ListViewArrays with dtype list(bool?)
  • All arrays have length 0

This reveals a type system issue where the fuzzer generated a struct with fields that require incompatible type conversions during mask operations.

Debug Output
FuzzArrayAction {
    array: StructArray {
        len: 0,
        dtype: Struct(
            StructFields {
                names: FieldNames(
                    [
                        FieldName(
                            "",
                        ),
                        FieldName(
                            "",
                        ),
                    ],
                ),
                dtypes: [
                    FieldDType {
                        inner: Owned(
                            Bool(
                                Nullable,
                            ),
                        ),
                    },
                    FieldDType {
                        inner: Owned(
                            List(
                                Bool(
                                    Nullable,
                                ),
                                NonNullable,
                            ),
                        ),
                    },
                ],
            },
            NonNullable,
        ),
        fields: [
            BoolArray {
                dtype: Bool(
                    Nullable,
                ),
                bits: BitBuffer {
                    buffer: Buffer<u8> {
                        length: 0,
                        alignment: Alignment(
                            1,
                        ),
                        as_slice: [],
                    },
                    offset: 0,
                    len: 0,
                },
                validity: AllValid,
                stats_set: ArrayStats {
                    inner: RwLock {
                        data: StatsSet {
                            values: [],
                        },
                    },
                },
            },
            ChunkedArray {
                dtype: List(
                    Bool(
                        Nullable,
                    ),
                    NonNullable,
                ),
                len: 0,
                chunk_offsets: PrimitiveArray {
                    dtype: Primitive(
                        U64,
                        NonNullable,
                    ),
                    buffer: Buffer<u8> {
                        length: 24,
                        alignment: Alignment(
                            8,
                        ),
                        as_slice: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...],
                    },
                    validity: NonNullable,
                    stats_set: ArrayStats {
                        inner: RwLock {
                            data: StatsSet {
                                values: [],
                            },
                        },
                    },
                },
                chunks: [
                    ListViewArray {
                        dtype: List(
                            Bool(
                                Nullable,
                            ),
                            NonNullable,
                        ),
                        elements: BoolArray {
                            dtype: Bool(
                                Nullable,
                            ),
                            bits: BitBuffer {
                                buffer: Buffer<u8> {
                                    length: 0,
                                    alignment: Alignment(
                                        1,
                                    ),
                                    as_slice: [],
                                },
                                offset: 0,
                                len: 0,
                            },
                            validity: AllValid,
                            stats_set: ArrayStats {
                                inner: RwLock {
                                    data: StatsSet {
                                        values: [],
                                    },
                                },
                            },
                        },
                        offsets: PrimitiveArray { ... },
                        sizes: PrimitiveArray { ... },
                        is_zero_copy_to_list: true,
                        validity: NonNullable,
                        stats_set: ArrayStats { ... },
                    },
                    ListViewArray { ... },
                ],
                stats_set: ArrayStats { ... },
            },
        ],
    },
    actions: [
        Mask(...),
    ],
}

Summary

Reproduction

  1. Download the crash artifact:

  2. Reproduce locally:

# The artifact contains array_ops/crash-c16aa01a615890a85d1b0fe54cebbd2103fa7833
cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-c16aa01a615890a85d1b0fe54cebbd2103fa7833 -- -rss_limit_mb=0
  1. Get full backtrace:
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-c16aa01a615890a85d1b0fe54cebbd2103fa7833 -- -rss_limit_mb=0

Auto-created by fuzzing workflow with Claude analysis

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions