Skip to content

Fuzzing Crash: Type mismatch in SequentialStreamAdapter (U8 vs U16) #5815

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: vortex-layout/src/sequence.rs:313 (SequentialStreamAdapter::poll_next)

Error Message:

assertion `left == right` failed: Sequential stream of u8 got chunk of u16.
  left: Primitive(U8, NonNullable)
 right: Primitive(U16, NonNullable)

Stack Trace:

   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<&vortex_dtype::dtype::DType, &mut vortex_dtype::dtype::DType>
   4: poll_next<core::pin::Pin<alloc::boxed::Box<(dyn futures_core::stream::Stream<Item=core::result::Result<(vortex_layout::sequence::SequenceId, alloc::sync::Arc<dyn vortex_array::array::Array, alloc::alloc::Global>), vortex_error::VortexError>> + core::marker::Send), alloc::alloc::Global>>>
             at ./vortex-layout/src/sequence.rs:313:13
   5: poll_next<alloc::boxed::Box<(dyn vortex_layout::sequence::SequentialStream<Item=core::result::Result<(vortex_layout::sequence::SequenceId, alloc::sync::Arc<dyn vortex_array::array::Array, alloc::alloc::Global>), vortex_error::VortexError>> + core::marker::Send), alloc::alloc::Global>>
   6: poll_next<core::pin::Pin<alloc::boxed::Box<(dyn vortex_layout::sequence::SequentialStream<Item=core::result::Result<(vortex_layout::sequence::SequenceId, alloc::sync::Arc<dyn vortex_array::array::Array, alloc::alloc::Global>), vortex_error::VortexError>> + core::marker::Send), alloc::alloc::Global>>, vortex_layout::layouts::repartition::{impl#4}::write_stream::{async_block#0}::{closure_env#0}>
   7: poll_next<futures_util::stream::stream::map::Map<core::pin::Pin<alloc::boxed::Box<(dyn vortex_layout::sequence::SequentialStream<Item=core::result::Result<(vortex_layout::sequence::SequenceId, alloc::sync::Arc<dyn vortex_array::array::Array, alloc::alloc::Global>), vortex_error::VortexError>> + core::marker::Send), alloc::alloc::Global>>, vortex_layout::layouts::repartition::{impl#4}::write_stream::{async_block#0}::{closure_env#0}>>
             at ./vortex-layout/src/sequence.rs:311:48

Root Cause: The SequentialStreamAdapter enforces that all chunks in a stream have the same dtype. The fuzzer discovered a case where a stream initialized for U8 (Nullable) received a chunk with U16 (NonNullable) dtype. This indicates a type inconsistency during stream processing, likely in the repartitioning or compression layer.

The crash happens when writing a nullable U8 PrimitiveArray through a dict layout strategy with compact compression. The stream processing pipeline (dict → repartition → compress → buffered → chunked) appears to be transforming the dtype incorrectly.

Debug Output
FuzzFileAction {
    array: PrimitiveArray {
        dtype: Primitive(
            U8,
            Nullable,
        ),
        buffer: Buffer<u8> {
            length: 57,
            alignment: Alignment(
                1,
            ),
            as_slice: [33, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, ...],
        },
        validity: Array(
            BoolArray {
                dtype: Bool(
                    NonNullable,
                ),
                bits: BitBuffer {
                    buffer: Buffer<u8> {
                        length: 8,
                        alignment: Alignment(
                            1,
                        ),
                        as_slice: [169, 255, 255, 255, 39, 213, 63, 0],
                    },
                    offset: 0,
                    len: 57,
                },
                validity: NonNullable,
                stats_set: ArrayStats {
                    inner: RwLock {
                        data: StatsSet {
                            values: [],
                        },
                    },
                },
            },
        ),
        stats_set: ArrayStats {
            inner: RwLock {
                data: StatsSet {
                    values: [],
                },
            },
        },
    },
    projection_expr: None,
    filter_expr: None,
    compressor_strategy: Compact,
}

Summary

Reproduction

  1. Download the crash artifact:

  2. Reproduce locally:

# The artifact contains file_io/crash-f34f3a6108ae41cb796a5e9d27f0f636135656f2
cargo +nightly fuzz run -D --sanitizer=none file_io file_io/crash-f34f3a6108ae41cb796a5e9d27f0f636135656f2 -- -rss_limit_mb=0
  1. Get full backtrace:
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none file_io file_io/crash-f34f3a6108ae41cb796a5e9d27f0f636135656f2 -- -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