GHSA-q97c-p368-75c4

    Dashboard / Vulnerabilities / GHSA-q97c-p368-75c4

    GHSA-q97c-p368-75c4

    Published: 28 Oct 2026Last Modified: 29 Oct 2026

    Summary: vLLM: Out-of-vocabulary prompt token id passes input validation and triggers a CUDA device-side assert (engine crash / DoS)

    Details: For a model whose vocabulary size is an exact multiple of the embedding padding size (64) — e.g. any Llama-2-family model, vocab 32000 — a single request carrying a pre-tokenized prompt with token id equal to the vocab size (32000) passes vLLM's input-id validation but is one past the last embedding row. At tensor-parallel size 1 the embedding lookup does not mask indices, so the id reaches `F.embedding` out of range and raises a CUDA device-side assert, which poisons the engine's CUDA context and takes the engine down. Any client that can send pre-tokenized input (`/v1/completions` with `prompt` as token ids, `/tokenize`-fed flows, or the `kv_transfer_params["prompt_token_ids"]` reuse path) can trigger it. ## Root cause `vllm/v1/engine/input_processor.py` accepts a token id when `id <= max(tokenizer.max_token_id, model_config.get_vocab_size() - 1)`. `vllm/tokenizers/hf.py` computes `max_token_id = max(max(vocab.values()), tokenizer.vocab_size)`. For Llama-2 tokenizers `max(vocab.values()) = 31999` but `tokenizer.vocab_size = 32000`, so `max_token_id = 32000` — one greater than the largest valid id. The engine bound therefore becomes `max(32000, 31999) = 32000`, and id 32000 is accepted. The model's embedding has `pad_vocab_size(32000, 64) = 32000` rows (no padding), valid indices 0..31999. At `VocabParallelEmbedding.forward` with `tp_size == 1` there is no masking, so index 32000 hits `F.embedding` out of range. ## Affected - tp=1 (single GPU per model — common per-copy layout). tp>1 masks via `get_masked_input_and_mask`, so the id is clamped, not an OOB — likely wrong output rather than a crash. - Models whose vocab is a multiple of 64 with `tokenizer.vocab_size` one past the max real id (Llama-2 family, vocab 32000, is the clear case). Qwen2.5 is NOT affected (padded headroom). ## Suggested fix max_token_id in vllm/tokenizers/hf.py now uses tokenizer.vocab_size - 1, so an id equal to the vocabulary size fails input validation instead of reaching the embedding. Fixed in [MR59491](https://github.com/vllm-project/vllm/pull/59491), released in v0.32.0. ## Reporter Shijie Lyu (GitHub shijie-lyu [email protected]). Reported privately per SECURITY. This advisory was fixed in [MR59491](https://github.com/vllm-project/vllm/pull/59491).

    Affected packages

    Package

    Name: vllm

    Purl: pkg:pypi/vllm

    Affected ranges

    Type: ECOSYSTEM

    Events:

    Introduced- 0
    Fixed -0.32.0

    Affected versions

    0.0.1

    Common Vulnerability Scoring System

    Attack Vector
    Network
    Adjacent
    Local
    Physical
    Privileges Required
    None
    Low
    High
    User Interaction
    None
    Required
    Scope
    Unchanged
    Changed
    Confidentiality
    None
    Low
    High
    Integrity
    None
    Low
    High
    Availability
    None
    Low
    High