Skip to content

Fuzzing Crash: Mask operation returns wrong dtype for nested struct with F16 fields #6351

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: vortex-array/src/compute/mask.rs:74 in the mask function

Error Message:

mask operation should succeed in fuzz test:
  Internal error: compute function mask returned a result of type {={}?, ={=f16?, =f16?}?}? but expected {={}?, ={=f16, =f16?}?}?
vortex.filter

Stack Trace:

   3: invoke
             at ./vortex-array/src/compute/mod.rs:149:13
   4: mask
             at ./vortex-array/src/compute/mask.rs:74:10
   5: run_fuzz_action
             at ./fuzz/src/array/mod.rs:640:33

Root Cause: The mask operation is incorrectly changing the nullability of nested struct fields.

The expected dtype is:

{={}?, ={=f16, =f16?}?}?

(Note: first F16 field is NonNullable)

But the mask function returns:

{={}?, ={=f16?, =f16?}?}?

(Note: first F16 field has been changed to Nullable)

The issue occurs when applying a mask operation to a deeply nested ChunkedArray containing StructArrays with F16 primitive fields. The mask operation is incorrectly propagating nullable to a field that should remain NonNullable (the first F16 field in the nested struct).

Array Structure:

  • ChunkedArray (length 110) with dtype: Struct(Nullable) containing 2 fields
  • Field 0: Empty struct Struct([], Nullable)
  • Field 1: Nested struct with 2 F16 fields
    • Field 1.0: F16(NonNullable) - This field's nullability is being incorrectly changed
    • Field 1.1: F16(Nullable)
  • All chunks have length 0 (empty arrays)

This is a type system invariant violation in the mask compute kernel where field-level nullability is not being preserved correctly during mask operations on nested structs.

Debug Output
FuzzArrayAction {
    array: ChunkedArray {
        dtype: Struct(
            StructFields {
                names: FieldNames(
                    [
                        FieldName(
                            "",
                        ),
                        FieldName(
                            "",
                        ),
                    ],
                ),
                dtypes: [
                    FieldDType {
                        inner: Owned(
                            Struct(
                                StructFields {
                                    names: FieldNames(
                                        [],
                                    ),
                                    dtypes: [],
                                },
                                Nullable,
                            ),
                        ),
                    },
                    FieldDType {
                        inner: Owned(
                            Struct(
                                StructFields {
                                    names: FieldNames(
                                        [
                                            FieldName(
                                                "",
                                            ),
                                            FieldName(
                                                "",
                                            ),
                                        ],
                                    ),
                                    dtypes: [
                                        FieldDType {
                                            inner: Owned(
                                                Primitive(
                                                    F16,
                                                    NonNullable,
                                                ),
                                            ),
                                        },
                                        FieldDType {
                                            inner: Owned(
                                                Primitive(
                                                    F16,
                                                    Nullable,
                                                ),
                                            ),
                                        },
                                    ],
                                },
                                Nullable,
                            ),
                        ),
                    },
                ],
            },
            Nullable,
        ),
        len: 110,
        chunks: [ ... ]
    },
    actions: [
        Mask( ... )
    ]
}

Summary

Reproduction

  1. Download the crash artifact:

  2. Reproduce locally:

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

Auto-created by fuzzing workflow with Claude analysis

Metadata

Metadata

Assignees

No one assigned

    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