AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

vLLMGHSA-pr7f-p5mw-fc87

vLLM: Incomplete CVE-2025-62164 remediation can be bypassed by concurrent prompt parts

vLLM

CVE-2026-73557 · Published Sep 4, 2026 · updated Sep 10, 2026

Medium
Fix: upgrade to 0.26.0 or later
GitHub advisory

Executive Summary

The follow-up protection for CVE-2025-62164 is incomplete at vLLM revision 26587f9519e22a5c4549ead7595ad9ca3229c4fd. It wraps serialized prompt-embedding reconstruction and dense conversion in torch.sparse.check_sparse_tensor_invariants(), but PyTorch 2.11.0 implements that context with save/enable/restore operations over process-global state. Two prompt-embedding parts in one /v1/chat/completions request are gathered concurrently on the event loop's default executor. When one context exits before the other loads its tensor, it can restore the global flag to False while the second part remains inside its guard.

In a deterministic run against hash-verified source from the affected revision, the actual target loader rejected an invalid sparse payload as a negative control. The frozen chat tracker then scheduled benign and malicious parts on distinct asyncio_0 and asyncio_1 threads. The benign context exited, the malicious loader observed the invariant flag disabled, and torch.load(weights_only=True) reconstructed indices [[10], [10]] for a declared shape of [3, 3]. The run intercepted the target's to_dense() call before it operated on the invalid tensor.

This primary trigger requires --enable-prompt-embeds, which is default-off, but it does not require renderer_num_workers > 1, a multimodal model, or --enable-mm-embeds. API...

Affected versions

PackageAffectedFixed in
vllm
PyPI
>= 0.21.0, < 0.26.00.26.0
Details and references

## Executive Summary The follow-up protection for CVE-2025-62164 is incomplete at vLLM revision `26587f9519e22a5c4549ead7595ad9ca3229c4fd`. It wraps serialized prompt-embedding reconstruction and dense conversion in `torch.sparse.check_sparse_tensor_invariants()`, but PyTorch 2.11.0 implements that context with save/enable/restore operations over process-global state. Two prompt-embedding parts in one `/v1/chat/completions` request are gathered concurrently on the event loop's default executor. When one context exits before the other loads its tensor, it can restore the global flag to `False` while the second part remains inside its guard. In a deterministic run against hash-verified source from the affected revision, the actual target loader rejected an invalid sparse payload as a negative control. The frozen chat tracker then scheduled benign and malicious parts on distinct `asyncio_0` and `asyncio_1` threads. The benign context exited, the malicious loader observed the invariant flag disabled, and `torch.load(weights_only=True)` reconstructed indices `[[10], [10]]` for a declared shape of `[3, 3]`. The run intercepted the target's `to_dense()` call before it operated on the invalid tensor. This primary trigger requires `--enable-prompt-embeds`, which is default-off, but it does **not** require `renderer_num_workers > 1`, a multimodal model, or `--enable-mm-embeds`. API authentication is optional in the stock server: middleware is installed only when CLI or environment API keys are supplied. The lab proves bypass of the follow-up guard, invalid sparse reconstruction, and guarded-sink reachability. Crash and memory-corruption consequences are conditional on the behavior documented by the published CVE. ## Background CVE-2025-62164 / [GHSA-mrw7-hf4f-83pf](https://github.com/vllm-project/vllm/security/advisories/GHSA-mrw7-hf4f-83pf) concerns client-controlled serialized `prompt_embeds` reaching `torch.load(weights_only=True)` and an invalid sparse tensor reaching `to_dense()`. The advisory attributes memory corruption, denial of service, and potential code execution to that historical unsafe operation. The remediation chronology matters for duplicate handling: - PR [#27204](https://github.com/vllm-project/vllm/pull/27204), merge commit [`58fab50d82838d5014f4a14d991fdb9352c9c84b`](https://github.com/vllm-project/vllm/commit/58fab50d82838d5014f4a14d991fdb9352c9c84b) on 2025-10-22, introduced the default-off `enable_prompt_embeds` gate. It did not add the sparse-invariant context. - Commit [`84e23d103d3483f944780d0d42bcf0993fd27e3a`](https://github.com/vllm-project/vllm/commit/84e23d103d3483f944780d0d42bcf0993fd27e3a) on 2025-12-15, titled `additional protection for CVE-2025-62164 (#30649)`, added the process-global sparse-invariant context around load, type check, and dense conversion. - Refactor commit [`f0a1c8453ad1c664c8a04c83fe545195fcd556eb`](https://github.com/vllm-project/vllm/commit/f0a1c8453ad1c664c8a04c83fe545195fcd556eb) on 2026-01-31 moved the guarded loader into `vllm/renderers/embed_utils.py` while preserving the same context. - Chat content-part commit [`14043dfecd35dd2f12b4d51eb9fa166184a0ca0f`](https://github.com/vllm-project/vllm/commit/14043dfecd35dd2f12b4d51eb9fa166184a0ca0f) on 2026-05-01 introduced `prompt_embeds` chat parts and the concurrent one-request schedule described here. This report therefore does not present the malformed sparse payload or `to_dense()` sink as new. It reports a distinct concurrency root cause and trigger: unsynchronized save/enable/restore of the process-global follow-up guard, reachable through the later multi-part chat scheduler. The affected revision pins PyTorch 2.11.0 in `pyproject.toml:10`. ## Vulnerability Details The target's `safe_load_prompt_embeds` performs the guarded operation in `vllm/renderers/embed_utils.py:16-39`: ```python with torch.sparse.check_sparse_tensor_invariants(): tensor = torch.load( BytesIO(pybase64.b64decode(embed, validate=Tr

CVSS 4.0
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Severity from
GitHub (reviewed advisory)
Weakness
CWE-362
Also known as
CVE-2026-73557, PYSEC-2026-3938

More vLLM advisories

All vLLM