Skip to content

[C++][Engine] Out-of-bounds read on invalid Substrait emit output_mapping index #54025

Closed

Description

@Nayana-Naik73

Describe the bug, including details regarding any error messages, version, and platform.

While reading the Substrait relation conversion I noticed that GetEmitInfo and ProcessEmitProject in cpp/src/arrow/engine/substrait/relation_internal.cc take each emit output_mapping value straight from the plan and use it to index input_schema->field(map_id) (and, for ProjectRel, the project expression vector) without any range check. Schema::field is only guarded by a DCHECK, so in release builds a plan with a negative or out-of-range output_mapping index reads past the end of the field vector, and the ProjectRel path also moves an out-of-bounds compute::Expression.

This is reachable from DeserializePlan / DeserializePlans on untrusted plan bytes, for essentially any relation that goes through the emit path (read, filter, join, fetch, sort, aggregate, set, project). In a debug build it trips the "Check failed: (i) < (num_fields())" DCHECK in Schema::field. ProcessExtensionEmit already rejects the same condition with Status::Invalid("Out of bounds emit index ..."), so I'd expect the other two emit helpers to do the same.

Minimal trigger: a ReadRel over a 3-column base schema with "common": {"emit": {"outputMapping": [0, 3]}} (or [-1, 1]).

Component(s)

C++

Activity

  1. added a commit that references this issue on Oct 17, 2026
  2. added a commit that references this issue on Nov 8, 2026
  3. added this to the 27.0.0 milestone on Nov 8, 2026
  4. kou commented on Nov 8, 2026

    @kou
    Member

    Issue resolved by pull request 53521
    #53521

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions