Skip to content

Handle RNN activation parameters safely - #31675

Merged
Tianlei Wu (tianleiwu) merged 5 commits into
mainfrom
fix/rnn-activation-alpha-beta-length-check
Aug 11, 2026
Merged

Handle RNN activation parameters safely#31675
Tianlei Wu (tianleiwu) merged 5 commits into
mainfrom
fix/rnn-activation-alpha-beta-length-check

Conversation

@apsonawane

@apsonawane Akshay Sonawane (apsonawane) commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This pull request prevents out-of-bounds reads of RNN activation parameters while preserving ONNX-spec-legal attribute lists.

RNN activation parameter handling:

  • Reuses the shared rnn::detail::ActivationFuncs normalization already used by ORT's LSTM and GRU kernels.
  • Consumes activation_alpha and activation_beta values only for activation functions that require them.
  • Applies activation-specific ONNX defaults when a required value is absent, including LeakyRelu, HardSigmoid, and Elu defaults.
  • Safely accepts empty, shorter, and longer parameter lists without indexing those lists by direction.

Unit test coverage:

  • Verifies mixed activations consume only the required alpha and beta values.
  • Verifies empty parameter attributes use activation-specific defaults.
  • Verifies a missing LeakyRelu alpha uses the ONNX default of 0.01.
  • Verifies extra alpha and beta entries are safely ignored.

The tests run explicitly on the CPU execution provider and no longer contain an unrelated DML skip.

Co-authored-by: Copilot <223556219@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens attribute validation for the CPU RNN kernel by enforcing expected lengths for activation_alpha and activation_beta, and adds unit tests to ensure invalid lengths fail model loading with clear error messages.

Changes:

  • Enforce activation_alpha/activation_beta vector lengths during RNN kernel construction.
  • Add a shared test helper plus two new negative tests validating failure behavior for short activation parameter vectors.

Reviewed changes

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

File Description
onnxruntime/core/providers/cpu/rnn/rnn.h Adds constructor-time activation_alpha/activation_beta length checks for CPU RNN.
onnxruntime/test/providers/cpu/rnn/rnn_op_test.cc Adds helper + new tests that assert model-load failure and error strings for invalid activation parameter lengths.

Comment thread onnxruntime/core/providers/cpu/rnn/rnn.h Outdated
Normalize activation_alpha/activation_beta for the unidirectional default
case (2 entries -> 1) to match existing activations handling, and improve
length error messages with singular/plural wording.

Add regression coverage that unidirectional models accept 2-entry
activation_alpha/activation_beta defaults, and update failure-message
expectations for the new wording.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@tianleiwu Tianlei Wu (tianleiwu) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing this — the underlying bug is real: Compute() indexes activation_alpha_[direction] / activation_beta_[direction] (rnn.cc:282) for direction < num_directions, so a short attribute list is an out-of-bounds read today.

My main concern is the shape of the fix rather than the intent. An exact-length ORT_ENFORCE is stricter than the ONNX spec and stricter than ORT's own LSTM/GRU kernels, so it can convert models that load today into hard session-creation failures. Details inline.

Summary of findings

  1. (high) Exact-length validation rejects spec-legal models. ONNX defines activation_alpha/activation_beta as values "consumed in the order of activation functions" — only activations that actually take an alpha/beta consume one, so the list length need not equal num_directions. ORT already implements this for LSTM/GRU via rnn::detail::ActivationFuncs / NormalizeActivationArgumentAndGetAlphaBetaCount in rnn_helpers.cc.
  2. (medium) The size() == 2 -> resize(1) special case silently discards user data and its comment is inaccurate (ONNX defines no default for these attributes, unlike activations).
  3. (medium, pre-existing but cemented here) GetAttrsOrDefault("activation_alpha", std::vector<float>(num_directions, 0.0F)) defaults every alpha to 0.0. For LeakyRelu the ONNX default is 0.01, Elu is 1.0, HardSigmoid is 0.2/0.5. So activations=["LeakyRelu"] with no activation_alpha silently computes plain Relu — a bigger correctness problem than the length check, and one that the ActivationFuncs path fixes for free.
  4. (minor) Test hygiene — dead DML skip, a test that pins the truncation workaround as a contract, and missing coverage for the empty-list / longer-than-num_directions / mixed-activation cases.

Compatibility note: if the strict check is kept as-is, it is a behavioral break for existing models and deserves a release note.

Happy to be pushed back on any of these if I've misread the intended scope.

Comment thread onnxruntime/core/providers/cpu/rnn/rnn.h Outdated
Comment thread onnxruntime/core/providers/cpu/rnn/rnn.h Outdated
Comment thread onnxruntime/test/providers/cpu/rnn/rnn_op_test.cc Outdated
Comment thread onnxruntime/test/providers/cpu/rnn/rnn_op_test.cc Outdated
Reuse the shared activation parameter normalizer so RNN follows ONNX alpha and beta consumption semantics, applies activation-specific defaults, and avoids out-of-bounds reads.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@apsonawane Akshay Sonawane (apsonawane) changed the title Validate RNN activation attribute lengths Handle RNN activation parameters safely Aug 10, 2026

@tianleiwu Tianlei Wu (tianleiwu) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the final aggregate diff. The previous activation-parameter concerns are addressed: CPU RNN now uses the shared ActivationFuncs normalization path, so alpha/beta values follow ONNX consumption semantics, missing values receive activation-specific defaults, extra entries are safe, and Compute() no longer indexes raw attribute vectors. The focused CPU tests cover mixed activations, empty and omitted parameters, default values, and extra entries. No remaining code-review findings; all required checks pass.

@tianleiwu
Tianlei Wu (tianleiwu) merged commit 3cee186 into main Aug 11, 2026
85 of 87 checks passed
@tianleiwu
Tianlei Wu (tianleiwu) deleted the fix/rnn-activation-alpha-beta-length-check branch August 11, 2026 19:20
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.

3 participants