senn-tech
Security
Security2026-08-17· By Franz Senn

When the Model Hands Out Your Neighbour's Answer

On August 11, 2026 the vLLM project published two security advisories. One is routine. The other describes something that has no clean drawer in the usual taxonomy of vulnerabilities: one user's answer can end up inside another user's response — with nobody attacking anything.

We did not learn about it from the trade press but from Germany's BSI warning service, which carried it three days later in an advisory wave. That is already the first lesson of this case, though not the most interesting one.

One line of CUDA arithmetic

The technical core of GHSA-7m6h-x95x-82q5 (CVE-2026-73558) is unspectacular, and instructive precisely for that reason. The act_and_mul_kernel activation kernel contains the expression blockIdx.x * 2 * d. With a large enough batch and a long enough sequence, that expression overflows the 32-bit range. The kernel then reads from the wrong region of memory — specifically, the region belonging to another request in the same batch.

The reporters did not derive this theoretically, they reproduced it: with meta-llama/Llama-3.2-1B-Instruct (dimension d = 8192), batch size 17 and 16,384 tokens of sequence length. The result was not some subtle residue but the extreme case — the last response in the batch was an exact copy of the first. The path there is notable too: the overflow was first filed as an ordinary correctness bug. Only the later security analysis showed that an arithmetic error here cuts straight through a tenant boundary.

From arithmetic error to data protection incidentTwo requestssame batch, 2 users32-bit overflowblockIdx.x * 2 * dForeign memoryrequest A reads request BAnswer copiedpartial or completeNotifiable?GDPR Art. 33
No access error, no missing authorisation — the separation between two users lived in a kernel's address arithmetic. (Quelle: vLLM Security Advisory GHSA-7m6h-x95x-82q5, August 11, 2026)

Why CVSS 5.3 misleads here

The advisory is rated CVSS 5.3 ("medium"), vector AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N. The low score comes mostly from the high attack complexity: to provoke the leak deliberately you have to land in the same batch as your victim and hit a suitable dimension — per the advisory, the effect appears when 2³² is divisible by d.

That rating answers the question "how hard is a deliberate attack?". For operating a self-hosted inference lane, a different question decides: how likely is the accident? And that needs no attacker at all — just two concurrent users, an ordinary batch size and a model whose intermediate dimension is a power of two, which is true of many common architectures.

This is exactly where a rented API and your own server part ways. With an API provider, tenant separation is their problem and their liability. Anyone self-hosting has taken it over — and may be discovering for the first time that it does not run through an access check, but through kernel code nobody in the building has ever read.

The self-test — and why the version number is not enough

We run three inference hosts and checked all three against both advisories. The result was not the traffic-light picture we expected:

  • The vision lane runs vLLM 0.27.1 — covered, for both advisories.
  • The chat lane runs 0.25.1.
  • The embedding and rerank containers run 0.20.2.

By pure version logic the latter two are affected. Checking the code path gives a different picture. The second advisory, GHSA-cqm8-jxg6-fqfq, blanket-lists < 0.27.0 as vulnerable — but describes a confusion in the DeepStream video backend, which per the advisory text was only introduced in version 0.26.0. On 0.25.1 that backend does not exist. The finding is moot there.

With the cross-user leak the situation is awkward in the opposite direction: the advisory gives the affected range as < 0.21.0 but the fix as >= 0.27.0. Together those make no sense. Anyone holding strictly to the range field declares 0.25.1 unaffected; anyone holding to the fix field declares it affected. This inconsistency is not a marginal detail — it is the reason automated version matching quietly says the wrong thing here.

The check order that prevents the false alarmRead versionvllm.__version__Check code pathdoes the feature exist?Check exposuremulti-tenant? reachable?Only then: findingor dismissed with reasons
Three of these four steps are missing from a pure version scan — and step two invalidated one of our two hits. (Quelle: Own assessment, August 17, 2026)

What to do now

Move to 0.27.x wherever several users share a lane. It is the only complete answer to the leak; there is no workaround, because the behaviour sits in the kernel and not in a configuration.

Classify single-tenant lanes honestly. If a lane demonstrably serves only one user, the cross-user leak is not a risk for it. That is a legitimate outcome — it just has to be evidenced rather than assumed, because an upstream gateway quietly turns many users into a single technical caller.

Document batch isolation. A data protection impact assessment for a local AI lane usually describes network separation, encryption and access rights. The question of which requests can share a batch belongs in that same list from now on — with shared inference it is the actual dividing line between two users.

Read advisory feeds directly. Both of these reports reached us through the CERT-Bund warning service, not through the trade press, where they did not appear at all. For self-hosted software, the authority and project level is not the slower source — it is the only one.

The real lesson

This case makes a poor scandal: medium rating, no exploitation in the wild, a clean fix. It makes a good model, though, for a class of failure that arrives with self-operated AI. Security thinking for classical software asks who is allowed to access what. With shared inference it must also ask whose data sits next to each other in the same computation step.

And the second half of this piece deserves to be taken more seriously than the first: of two formally matching hits, one survived the code-path check. A tool that only compares version numbers would have reported both — and the next time, nobody looks.

Questions?
Does an attacker have to do anything for this bug to expose data?+

No, and that is the unusual part. This is an arithmetic error in an activation kernel, not an access control problem. It takes effect as soon as two requests are processed in the same inference batch and the dimensions line up unfavourably. An attacker can bring that about deliberately, but does not have to — under sufficient concurrent load it happens on its own. That is exactly why the low CVSS score misleads here: it measures how hard a deliberate attack is, not how likely an accident is.

Is comparing the version number against the advisory enough?+

No. With these two vLLM advisories, doing exactly that leads you astray. The DoS advisory lists every version below 0.27.0 as affected, yet describes a video backend that was only introduced in 0.26.0 — so on 0.25.1 the vulnerable code path does not exist at all. Conversely, the leak advisory contradicts itself by naming versions below 0.21.0 as affected while giving 0.27.0 as the fix. Only the question of whether the described code path exists in your version turns a version number into a finding.

Does this affect embedding and rerank models too, or only chat?+

By the mechanism, yes. The affected kernel computes the activation in the MLP block and is traversed by embedding and rerank models just as it is by generative ones. The practical difference lies in the output: with a chat model the leak is readable text, with an embedding model it is a vector. Both are user data, but only one of them is immediately obvious — which arguably makes the embedding lane more dangerous, not less.