[Security][Rust Frontend] Add input validation to gRPC and HTTP stop_token_ids - #45569
jperezdealgaba wants to merge 2 commits into
Conversation
…token_ids Add missing input validation to the Rust gRPC Generate frontend and HTTP stop_token_ids to prevent denial-of-service via EngineCore termination from malformed requests. - Validate prompt token_ids, stop_token_ids, allowed_token_ids, logit_bias, logprobs count, and logprob_token_ids against vocab size and GPU sampler buffer caps in the gRPC converter - Guard CandidateTokens.top_n u32->i32 cast overflow and cap at max_logprobs (default 20) - Add validate_stop_token_ids to HTTP completions and chat completions paths - Thread max_logprobs through TextBackend -> TextLlm -> ChatLlm -> AppState Signed-off-by: Juan Pérez de Algaba <jperezde@redhat.com> Signed-off-by: jperezde <jperezde@redhat.com>
BugenZhao
left a comment
There was a problem hiding this comment.
Thanks for the work. The newly added validations are valuable; however, I personally think we're mixing too many orthogonal things in a single PR, while each of them only covers basic validation rather than semantic parity with the Python frontend.
For example, in this PR we hardcode max_logprobs to DEFAULT_MAX_LOGPROBS instead of respecting the CLI option --max-logprobs. I've opened a PR for a more thorough implementation: #45674
|
Also, I think we may need some refactoring of the validation first: it is currently done within the handlers for different endpoints, so it can be very easy to miss some of them (just like that we missed it in gRPC, which this PR is going to address). Ideally we should push the validation down to a common/shared layer to avoid such duplication and make it more future-proof. |
|
This pull request has merge conflicts that must be resolved before it can be |
|
Closing this MR as it was included here: #45685 |
Summary
Generate/GenerateStreamfrontend to reject malformed requests before they reach EngineCorestop_token_idsvocab-range validation to the Rust HTTP completions and chat completions pathsmax_logprobs(default 20) throughTextBackend->TextLlm->ChatLlm->AppStatefor logprobs count enforcementMotivation
The Rust gRPC converter (
convert.rs) forwarded user-controlled fields intoSamplingParamswithout the bounds checking that the Python path enforces inSamplingParams.verify()and the GPU sampler's fixed-size buffers. A caller could submit a single request with out-of-range token IDs, oversized field lists, or uncapped logprob counts, causing EngineCore to hit a fatal assertion or OOM and requiring a full service restart.The Rust HTTP path also lacked
stop_token_idsvocab-range validation, allowing the same class of crash through the OpenAI-compatible API.Security Advisories Fixed
CandidateTokens.top_nmax_logprobscap;u32->i32cast can overflowoutput_candidates.token_idsMAX_LOGPROB_TOKEN_IDS(128) and vocab rangeprompt.token_idsstop_token_idsallowed_token_ids,logit_bias,stop_token_idsChanges
gRPC validation (
rust/src/server/src/grpc/convert.rs):ValidationBoundsstruct populated fromAppStatevocab sizes andmax_logprobstoken_ids(vocab range),stop_token_ids(count <= 128, vocab range),allowed_token_ids(count <= 1024, vocab range),logit_bias(count <= 1024, vocab range), logprobs count (top_n<=max_logprobs, overflow guard), andlogprob_token_ids(count <= 128, vocab range)INVALID_ARGUMENTbefore reaching the engineHTTP stop_token_ids validation (
rust/src/server/src/routes/openai/):validate_stop_token_ids()inutils/token_ids.rscompletions/validate.rsandchat_completions/validate.rsmax_logprobs plumbing (
rust/src/text/,rust/src/chat/,rust/src/server/src/state.rs):max_logprobs()method toTextBackendtrait (default 20), threaded throughTextLlm,ChatLlm, andAppStateValidation constants (matching Python/GPU sampler caps)
MAX_LOGPROB_TOKEN_IDSsampling_params.MAX_LOGPROB_TOKEN_IDSMAX_NUM_ALLOWED_TOKEN_IDSlogit_bias.MAX_NUM_ALLOWED_TOKEN_IDSMAX_NUM_LOGIT_BIAS_TOKENSlogit_bias.MAX_NUM_LOGIT_BIAS_TOKENSMAX_NUM_STOP_TOKEN_IDSlogit_bias.MAX_NUM_STOP_TOKEN_IDSTest plan
grpc/convert.rscovering all rejection cases (out-of-vocab, oversized, overflow) and valid pass-throughgrpc::converttests passstop_token_idscoverage)vllm-textandvllm-chatcrate tests passcargo clippyclean (0 warnings)cargo fmtclean