Skip to content

Fix OOB read in ConcatSliceElimination and UnsqueezeElimination#27718

Closed
vraspar wants to merge 1 commit intomainfrom
vraspar/fix-concat-slice-elimination-oob-read
Closed

Fix OOB read in ConcatSliceElimination and UnsqueezeElimination#27718
vraspar wants to merge 1 commit intomainfrom
vraspar/fix-concat-slice-elimination-oob-read

Conversation

@vraspar
Copy link
Copy Markdown
Contributor

@vraspar vraspar commented Mar 17, 2026

Description

GetSliceInfo in ConcatSliceElimination returns true with empty axes/steps vectors when a Slice node omits optional inputs.
The caller FuseConcatSliceSubgraph then accesses axes[0] and steps[0] without checking, reading uninitialized InlinedVector

Root Cause

GetSliceInfo did not populate ONNX spec defaults for omitted optional Slice inputs:

  • Opset v1: axes attribute is optional; if absent, vector stays empty
  • Opset ≥10: if axes input doesn't exist, the entire axes/steps parsing block is skipped

Fix
concat_slice_elimination.cc: Populate ONNX spec defaults before returning from GetSliceInfo. axes defaults to [0, 1, ...,
len(starts)-1], steps defaults to all 1s. This matches how ORT's Slice kernel handles missing inputs in slice_helper.h.

unsqueeze_elimination.cc (related variant): Added duplicate axis detection to prevent an iterator from reading past
tensor_proto.dims().cend() when axes contain duplicates.

Testing

  • Added ConcatSliceEliminationTest_NoAxesSteps regression test

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes optimizer-time out-of-bounds/UB issues in two graph transforms by aligning Slice/Unsqueeze handling with ONNX/ORT semantics, and adds a regression test to prevent reintroducing the Concat+Slice crash.

Changes:

  • ConcatSliceElimination: Populate ONNX default axes and steps when optional Slice inputs/attributes are omitted, preventing OOB reads in fusion logic.
  • UnsqueezeElimination: Add duplicate-axis detection to avoid iterator OOB when computing the new initializer shape.
  • Tests: Add a regression test covering ConcatSliceElimination with Slice nodes omitting optional axes/steps.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
onnxruntime/test/optimizer/graph_transform_test.cc Adds regression coverage for ConcatSliceElimination when Slice omits optional inputs.
onnxruntime/core/optimizer/unsqueeze_elimination.cc Prevents duplicate-axis cases from triggering invalid shape iteration during elimination.
onnxruntime/core/optimizer/concat_slice_elimination.cc Adds ONNX-default axes/steps population to avoid OOB reads during fusion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +145 to +156
// Per ONNX Slice spec: if axes not provided, default to [0, 1, ..., len(starts)-1].
if (axes.empty()) {
axes.reserve(starts.size());
for (int64_t i = 0, limit = static_cast<int64_t>(starts.size()); i < limit; ++i) {
axes.push_back(i);
}
}

// Per ONNX Slice spec: if steps not provided, default to all 1s.
if (steps.empty()) {
steps.assign(starts.size(), int64_t{1});
}
@vraspar
Copy link
Copy Markdown
Contributor Author

vraspar commented Mar 18, 2026

Closing the PR in favor of #27638

@vraspar vraspar closed this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants