Validate min_tokens_to_keep in the Sampling op to prevent an out-of-bounds access - #29871
Merged
David Fan (jiafatom) merged 2 commits intoJul 25, 2026
Merged
Conversation
…ccess The Sampling contrib operator reads the integer graph attribute min_tokens_to_keep without validation and uses it in an unsigned subtraction against vocab_size to bound a heap-buffer loop in cumulate_and_filter(). When min_tokens_to_keep > vocab_size, the expression (size_t)vocab_size - (size_t)min_tokens_to_keep underflows to a value near 2^64, so the loop walks the cumulative_probs buffer (batch_size * vocab_size floats) past its end, causing an out-of-bounds read-modify-write and a crash at the first Run(). Validate min_tokens_to_keep is in [0, vocab_size) at the top of Sample() before any buffer access, so an out-of-range model fails cleanly with a Status error. vocab_size is already validated positive beforehand. The same guard is applied to the CUDA sampling path, where min_tokens_to_keep feeds LaunchFilterLogitsKernel. Adds SamplingTest.InvalidMinTokensToKeep_CPU and a testdata model with an out-of-range min_tokens_to_keep to cover the fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 76040e4c-13bf-459e-affe-a2a6569f312f
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the com.microsoft contrib Sampling operator by validating the min_tokens_to_keep graph attribute before it can be used in CPU/CUDA filtering logic, preventing arithmetic underflow/invalid indexing that could lead to heap out-of-bounds access during Run().
Changes:
- Add runtime validation in CPU and CUDA
Sample()helpers to requiremin_tokens_to_keepbe in[0, vocab_size). - Add a CPU regression test that runs an invalid model (
min_tokens_to_keepset far abovevocab_size) and assertsRun()fails with a clear error instead of crashing.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| onnxruntime/test/contrib_ops/sampling_test.cc | Adds a CPU regression test to ensure invalid min_tokens_to_keep fails cleanly at runtime. |
| onnxruntime/contrib_ops/cuda/transformers/sampling_cuda_helper.h | Adds a guard rejecting out-of-range min_tokens_to_keep before launching CUDA filtering logic. |
| onnxruntime/contrib_ops/cpu/transformers/sampling_cpu_helper.h | Adds a guard rejecting out-of-range min_tokens_to_keep before CPU-side cumulative filtering. |
- Reword the CUDA-side comment to accurately describe the filter logits kernel's `idx + min_tokens_to_keep < vocab_size` gating rather than a subtraction-based loop bound. - Refactor the CPU regression test into a shared helper and add a USE_CUDA / HasCudaEnvironment-guarded GPU variant so the CUDA-side guard is covered as well. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 76040e4c-13bf-459e-affe-a2a6569f312f
Tianlei Wu (tianleiwu)
approved these changes
Jul 25, 2026
David Fan (jiafatom)
deleted the
fix/sampling-min-tokens-to-keep-validation
branch
July 25, 2026 23:02
This was referenced Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
Samplingcontrib operator (com.microsoft, default CPU EP) reads the integer graph attributemin_tokens_to_keepwithout validation and uses it in an unsigned subtraction againstvocab_sizeto bound a heap-buffer loop. Whenmin_tokens_to_keep > vocab_size, the expression(size_t)vocab_size - (size_t)min_tokens_to_keepunderflows to a value near2^64, socumulate_and_filter()walks thecumulative_probsbuffer (sizebatch_size * vocab_sizefloats) past its end, causing an out-of-bounds read-modify-write and a crash. This happens at the firstRun()with no special flags.Root cause
onnxruntime/contrib_ops/cpu/transformers/sampling_cpu_helper.h,cumulate_and_filter():vocab_sizeis validated ([1, decoder-logits-width]inGreedySearchProcessLogits), butmin_tokens_to_keepis copied verbatim from the model (sampling_parameters.cc:18; schema default0atcontrib_defs.cc:1369).Fix
Validate
min_tokens_to_keepis in[0, vocab_size)at the top ofSample()— before any buffer access — so an out-of-range model fails cleanly with aStatuserror instead of accessing memory out of bounds. Applied to both the CPU (sampling_cpu_helper.h) and CUDA (sampling_cuda_helper.h, where the same attribute feedsLaunchFilterLogitsKernel) paths.vocab_sizeis already validated positive beforeSample()runs.Testing
SamplingTest.InvalidMinTokensToKeep_CPU: loads a model withmin_tokens_to_keep=1000000and assertsRun()fails with a clear error rather than crashing.tiny_gpt2_sampling_invalid_min_tokens.onnx(clone oftiny_gpt2_sampling.onnxwith the attribute overwritten).0..vocab_size-1) and rejects values that underflow the loop bound.