Ce mail provient de l'extérieur, restons vigilants

=====================================================================


                            CERT-Renater

                Note d'Information No. 2026/VULN719
_____________________________________________________________________


DATE                : 03/07/2026

HARDWARE PLATFORM(S): /

OPERATING SYSTEM(S): Systems running vLLM versions prior to 3.7.6,
                                    3.6.22, 2.11.51.
 
=====================================================================

https://github.com/vllm-project/vllm/security/advisories/GHSA-8wr5-jm2h-8r4f
https://github.com/vllm-project/vllm/security/advisories/GHSA-v82g-2437-67m2
https://github.com/vllm-project/vllm/security/advisories/GHSA-33cg-gxv8-3p8g
_____________________________________________________________________


Remote DoS in vLLM via Invalid Recovered Token Reinjection
High
jperezdealgaba published GHSA-8wr5-jm2h-8r4f 

Package
vllm (pip)

Affected versions
=< 0.17.1

Patched versions
>=0.24.0


Description

Summary

A frontend-legal multi-request speculative workload can make vLLM
produce an out-of-vocabulary recovered token equal to vocab_size,
convert that value to -1 when choosing the next live token for a
request, and then feed that -1 back into the next drafter input ids.
On Qwen3 GPTQ this reaches the worker-side drafting / attention path
and crashes the engine with a GPU device-side assert.

The same issue is reachable through the public gRPC request surface
by sending a specific overlapping Generate / Abort sequence.
Impact

    A remote client that can send public gRPC generation requests
    can crash the shared vLLM engine worker
    The triggering request sequence aborts concurrent requests and
    prevents later requests from completing until the worker is
    restarted 
    In shared deployments, this is a service-wide denial of service
    for other clients, not just a failure isolated to the attacking
    requests 
    The failure is reproducible, so repeated request sequences can
    sustain the outage


Affected version

    Confirmed on vLLM 0.17.1
    Earlier and later versions have not been checked yet in this
report


Repro model

    Official Hugging Face repo:
        Qwen/Qwen3-0.6B-GPTQ-Int8
    Anyone wants to reproduce the bug with my PoC scripts should
download Qwen3-0.6B-GPTQ-Int8 first


Trigger chain

    A legal multi-request speculative workload keeps structured-output
    state, speculative decoding, overlap, and request cancellation
    active in the same live engine.
    During rejection sampling, vLLM produces a recovered token equal
    to the model vocab_size boundary value.
    That recovered token appears in position 0 of the sampled
    speculative row for a live request. The same row also contains
    trailing padding entries equal to -1, but those padding entries are
    not the key fault by themselves.
    The next-token preparation step treats the position-0 recovered
    token as the real next token for that request and converts that
    out-of-vocabulary value to -1.
    The drafter writes that converted -1 back into the live next-step
    input-id row for the request.
    The drafting / embedding / attention path later consumes that live
    invalid token and the worker crashes on GPU.


Details

Simple example

The important distinction is:

    trailing -1 values in a speculative row can be ordinary padding
    the bug appears when the first live token for a request becomes
    151936 == vocab_size, and that live token is then converted into -1

In simplified form, the bad transition looks like this:

sampled speculative row:
[151936, -1, -1, -1, ...]

At this point, the trailing -1 values are only padding. The critical
problem is that the first position holds 151936, which is out of
vocabulary and is being treated as the request's real next token.

Then vLLM prepares the next-token buffer:

next_token_ids:
[-1, ...]

Finally, that converted -1 is written back into the live model
input ids:

input_ids_after:
[-1, 0, 0, 0, ...]

The crash happens because the live next token became -1 and was
later consumed by the drafting / embedding / attention path, not
merely because the speculative row contained padded -1 entries.


Trigger path in code

    The workload is frontend-legal. The requests use normal
    SamplingParams features such as structured outputs, stop,
    bad_words, min_tokens, and streaming overlap. No malformed
    token-id list is required at the request boundary.
    In speculative decoding, the rejection sampler can generate
    recovered tokens when drafted tokens are rejected.

    # vllm/v1/sample/rejection_sampler.py
    def sample_recovered_tokens(...):
        recovered_token_ids = torch.empty_like(draft_token_ids)
        sample_recovered_tokens_kernel[(batch_size, max_spec_len)](...)
        return recovered_token_ids

    On the verified Qwen3 run, the recovered-token trace shows
    recovered_token_ids[0] = 151936, which is exactly vocab_size for this
    checkpoint.
    The speculative proposer then prepares the next-token row from the sampled
    speculative row.

    # vllm/v1/spec_decode/eagle.py
    def prepare_next_token_ids_padded(...):
        ...
        eagle_prepare_next_token_padded_kernel[grid](
            sampled_token_ids,
            discard_request_mask,
            backup_tokens_gpu,
            next_token_ids,
            valid_sampled_tokens_count,
            gpu_input_batch.vocab_size,
            ...
        )
        return next_token_ids, valid_sampled_tokens_count

    In the verified trace, this step receives a sampled row beginning with
    151936, followed by -1 padding. The important point is that 151936
    occupies the first live token position for the request. This step then
    produces next_token_ids[0] = -1, meaning the live next token for the
    request has been converted to -1.
    The drafter then rotates the draft input ids and inserts those
    next_token_ids back into the live input-id buffer.

    # vllm/v1/spec_decode/eagle.py
    def set_inputs_first_pass(...):
        ...
        self.input_ids[token_indices_to_sample] = next_token_ids

    In the verified trace, this produces input_ids_after[0] = -1.
    The model-side embed path later consumes those input ids.

    # vllm/model_executor/models/qwen2.py
    def embed_input_ids(self, input_ids: torch.Tensor) -> torch.Tensor:
        return self.embed_tokens(input_ids)

    In the verified trace, this is the first point where the converted -1
    becomes visible as a real model input. The bug is not merely that the
    sampled speculative row contained padding -1; the bug is that the live
    next token for the request became -1 and was written back into input ids.
    After that point, the visible sink depends on timing and backend state. On
    the attached Qwen3 reproducer, the engine commonly dies later in the
    drafting / attention path with CUDA error: device-side assert triggered,
    for example under flash_attn_varlen_func(...).

Local script breakdown

repro_g4_recovered_minus1_local.py is a standalone local reproducer.

    It reads the Qwen3 checkpoint path from VLLM_POC_G4_MODEL or the built-in
    /path/to/qwen3 placeholder
    It creates EngineCore directly without any external helper dependency
    It submits one fixed multi-request workload that preserves the same overlap
    and speculative-decoding state needed for the bug
    It writes:
        request_payloads.json
        repro_config.json
        timeline.json
        responses.json
        error.txt
        recovered_chain_trace.jsonl
    recovered_chain_trace.jsonl is the key attribution artifact. It records the
    recovered-token chain directly from the standalone reproducer

gRPC script breakdown

repro_g4_recovered_minus1_grpc.py is a standalone public gRPC reproducer.

    It reads the Qwen3 checkpoint path from VLLM_POC_G4_MODEL or the built-in
    /path/to/qwen3 placeholder
    It starts a temporary vllm.entrypoints.grpc_server process
    It sends only public Generate and Abort RPCs
    It submits one fixed overlapping request sequence that preserves the same
    speculative-decoding state needed for the bug
    After the crash window, it sends one more public Generate probe request to
    confirm that later gRPC requests also fail after the worker dies
    It writes:
        request_payloads.json
        timeline.json
        server_command.json
        responses.json
        post_crash_probe.json
        server.stdout.log
        server.stderr.log

Observed result

Local repro typically ends with:

    a recovered-token trace showing:
        sample_recovered_tokens_return -> recovered_token_ids[0] = 151936
        prepare_next_token_ids_padded -> next_token_ids[0] = -1
        set_inputs_first_pass -> input_ids_after[0] = -1
        embed_input_ids_out_of_range -> input_ids[0] = -1
    CUDA error: device-side assert triggered
    a fatal engine-side failure

gRPC repro typically ends with:

    the triggering gRPC requests failing with
    INTERNAL: EngineCore encountered an issue. See stack trace (above) for the root cause.
    server logs showing the worker dies with
    CUDA error: device-side assert triggered
    a later public probe request also failing after the worker is dead

This demonstrates that the issue is reachable through the public gRPC request
surface, not only through a local reproducer.
Log snippets
Local recovered-chain trace

sample_recovered_tokens_return:
  recovered_token_ids = [151936, ...]
  vocab_size = 151936

prepare_next_token_ids_padded:
  sampled_token_ids_head = [[151936, -1, -1, ...], ...]
  next_token_ids = [-1, ...]

set_inputs_first_pass:
  input_ids_after = [-1, 0, 0, 0, ...]

embed_input_ids_out_of_range:
  input_ids = [-1, 0, 0, 0, ...]

gRPC server log

torch.AcceleratorError: CUDA error: device-side assert triggered
...
vllm.v1.engine.exceptions.EngineDeadError: EngineCore encountered an
issue. See stack trace (above) for the root cause.
...
Error in Generate for request post_crash_probe
vllm.v1.engine.exceptions.EngineDeadError: EngineCore encountered an
issue. See stack trace (above) for the root cause.


Root cause

This is a speculative-decoding state-handling bug, not an invalid
frontend token-id input bug.

The root cause is that a recovered speculative token can become
equal to vocab_size, then be selected as the live next token for
a request, then be converted to -1, and that converted -1 is still
written back into live drafter input ids and later consumed by the
drafting / embedding / attention path.

For the Qwen3 checkpoint used here:

    151936 == vocab_size

This value should be described as the model vocab_size boundary
value, not as a legal token id.

Attachments

The attached bundle for this report should contain:

    repro_g4_recovered_minus1_local.py
    repro_g4_recovered_minus1_grpc.py

These two standalone scripts are sufficient to reproduce the issue
and its public gRPC reachability.

Fix

A fix for this vulnerability has been merged in: #44744


Severity
High
7.5/ 10

CVSS v3 base metrics
Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID
CVE-2026-54234

Weaknesses
Weakness CWE-20

Credits

    @NeilAlfred NeilAlfred Reporter
    @jperezdealgaba jperezdealgaba Coordinator


_____________________________________________________________________


Speech-to-text upload size limit is enforced after full UploadFile
read

Moderate
jperezdealgaba published GHSA-v82g-2437-67m2

Package
vllm (pip)

Affected versions
>= 0.22.0, <= 0.23.0

Patched versions
>=0.24.0


Description

Summary

Current-head vLLM documents VLLM_MAX_AUDIO_CLIP_FILESIZE_MB as the
maximum audio file size accepted by the speech-to-text APIs. The
default is 25 MB. vllm/envs.py also describes files larger than this
value as rejected.

The /v1/audio/transcriptions and /v1/audio/translations routes call
await request.file.read() before vLLM checks that limit. In FastAPI
and Starlette, UploadFile.read() returns bytes from the uploaded file
object; when called without a size argument, the route materializes
the remaining file contents. vLLM then performs the compressed
file-size check later in _preprocess_speech_to_text() against the
already-created bytes object.

As a result, the documented compressed audio file-size limit does not
bound the memory allocated by vLLM endpoint code before validation.
An oversized multipart upload can cause vLLM to allocate memory
proportional to the uploaded file size before rejecting the request
as too large.

This is distinct from GHSA-6pr9-rp53-2pmc, which covered decoded PCM
expansion after compressed input was accepted. This report covers
compressed upload materialization before compressed-size validation.


Technical Details

The upload routes perform an unbounded read before vLLM checks the
documented compressed audio file-size limit:

    vllm/entrypoints/speech_to_text/transcription/api_router.py: audio_data = await request.file.read()
    vllm/entrypoints/speech_to_text/translation/api_router.py: audio_data = await request.file.read()
    vllm/entrypoints/speech_to_text/base/serving.py later checks: if len(audio_data) / 1024**2 > self.max_audio_filesize_mb

There is no route-level check of request.file.size, Content-Length,
a bounded read(max_bytes + 1), or a streaming copy that stops at the
configured limit before the full file is materialized.

This does not appear to be intended behavior. vLLM's security guide
treats request-controlled resource use as a security boundary: for
example, requests that exceed VLLM_MAX_N_SEQUENCES are rejected before
reaching the engine. The speech-to-text upload limit is documented
in the same spirit as an API enforced limit, but the first vLLM check
happens after the over-limit upload has already been copied into a
bytes object.


Impact

Attack requirements:

    the deployment exposes /v1/audio/transcriptions or
/v1/audio/translations;
    a speech-to-text capable model/task is configured; and
    the caller can submit requests to the endpoint, including
any API key the deployment requires.

An API caller who meets those requirements can send an oversized
audio file. vLLM reads the full uploaded file into memory before
applying the configured compressed audio file-size limit. This
can create memory pressure or, depending on process/container
limits and concurrency, terminate the process before the request
is rejected.

Suggested severity: Moderate,
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H (6.5),
CWE-770/CWE-400.

The impact is availability-only. I am not claiming code execution,
data access, cross-tenant data exposure, parser-level multipart
memory exhaustion, or persistence after process restart.
Deployment body-size limits at a reverse proxy or ASGI layer can
mitigate the issue before vLLM sees the request, but vLLM's own
documented file-size limit does not currently provide that memory
boundary.


Suggested Fix

Enforce the compressed audio upload limit before the unbounded read:

    Check reliable upload size metadata before reading when available.
    Read at most max_bytes + 1 bytes in chunks as a defense-in-depth
guard against missing or unreliable metadata.
    Share the helper between transcription and translation routes.
    Add regression tests that prove an over-limit UploadFile is
rejected without calling an unbounded read().

The important property is that over-limit compressed uploads are
rejected before vLLM allocates the full uploaded file as bytes.


References

    vLLM security policy: https://github.com/vllm-project/vllm/security/policy
    vLLM speech-to-text docs: https://docs.vllm.ai/en/latest/serving/online_serving/speech_to_text/
    vLLM security guide, request parameter resource limits: https://docs.vllm.ai/en/latest/usage/security/
    vLLM vulnerability management docs: https://docs.vllm.ai/en/latest/contributing/vulnerability_management/
    FastAPI file uploads: https://fastapi.tiangolo.com/reference/uploadfile/
    Starlette uploaded files: https://www.starlette.io/requests/
    Adjacent published audio advisory: https://github.com/vllm-project/vllm/security/advisories/GHSA-6pr9-rp53-2pmc
    Request-parameter resource DoS precedent: https://github.com/vllm-project/vllm/security/advisories/GHSA-3mwp-wvh9-7528


Appendix: Affected Version

Validated against current head:

    commit: 1033ffac2eccf986fdd880f4dee64ca3b22c63c9
    described version: v0.22.1rc0-491-g1033ffac2e

Known affected range: current head. I have not determined the
introducing commit or release range.

Appendix: Proof Of Vulnerability

The attached proof is a non-destructive static probe. It does
not upload a large file or contact a running vLLM server:

python3 attached-evidence/poc/audio_upload_size_precheck_probe.py

Observed result:

{
  "pov": "this report",
  "validated": true,
  "default_limit_mb": 25,
  "documented_api_limit": true,
  "routes": {
    "transcription_route": {
      "unbounded_upload_read": true,
      "early_size_guard_before_read": false,
      "chunked_bounded_read": false
    },
    "translation_route": {
      "unbounded_upload_read": true,
      "early_size_guard_before_read": false,
      "chunked_bounded_read": false
    }
  },
  "late_size_check": {
    "present": true
  }
}

Expected behavior: vLLM rejects over-limit audio files before
materializing the entire upload into memory in vLLM endpoint code.

Actual behavior: the route materializes the upload into memory
first, and only then does vLLM reject the request as exceeding
VLLM_MAX_AUDIO_CLIP_FILESIZE_MB.


Severity
Moderate
6.5/ 10

CVSS v3 base metrics
Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

CVE ID
CVE-2026-55646

Weaknesses
Weakness CWE-400
Weakness CWE-770

Credits

    @rexpository rexpository Reporter
    @jperezdealgaba jperezdealgaba Coordinator

_____________________________________________________________________



DoS caused by sending `/v1/completions` with prompt embeds payload
with models that use M-RoPE

Moderate
jperezdealgaba published GHSA-33cg-gxv8-3p8g

Package
vllm (pip)

Affected versions
>=0.12.0

Patched versions
>=0.24.0


Description

Summary

Short summary of the problem. Make the impact and severity as clear as
possible. For example: An unsafe deserialization vulnerability allows any
unauthenticated user to execute arbitrary code on the server.

Sending a pure prompt embeds payload in a /v1/completions request with a
model using M-RoPE causes the EngineCore to fail an assertion and fatally
crash, shutting down the entire server application.

Any remote user who is authorized to make a /v1/completions endpoint can
trivially make such a request and induce a crash.


Details

Give all details on the vulnerability. Pointing to the incriminated source
code is very helpful for the maintainer.

In commit 56669c1, a simple assert intended to be a type-narrowing assert was
added to the _init_mrope_positions method in GPUModelRunner (the offending
line on main at the time of writing:

vllm/vllm/v1/worker/gpu_model_runner.py

Lines 1588 to 1607 in 2d481f8
 def _init_mrope_positions(self, req_state: CachedRequestState): 
     model = self.get_model() 
     assert supports_mrope(model), "M-RoPE support is not implemented." 
     assert req_state.prompt_token_ids is not None, ( 
         "M-RoPE requires prompt_token_ids to be available." 
     ) 
     mrope_model = cast(SupportsMRoPE, model) 
  
     # `prompt_embeds` is a passthrough modality (no grid_thw), models' 
     # M-RoPE code assumes per-feature grid info, so filter it out. The 
     # prompt_embeds positions are treated as text positions for M-RoPE. 
     mrope_features = [ 
         f for f in req_state.mm_features if f.modality != "prompt_embeds" 
     ] 
     req_state.mrope_positions, req_state.mrope_position_delta = ( 
         mrope_model.get_mrope_input_positions( 
             req_state.prompt_token_ids, 
             mrope_features, 
         ) 
     ) 
).

assert req_state.prompt_token_ids is not None, (
            "M-RoPE requires prompt_token_ids to be available."
        )

This type narrowing assert is to prevent mypy errors later in the function
because None is not a valid type for mrope_model.get_mrope_input_positions.
Unfortunately, this assertion is not always true. /v1/completions requests
that specify prompt=None and prompt_embeds=<not none> will indeed create a
CachedRequestState where prompt_token_ids is None. This triggers the
assertion, which in turn crashes the EngineCore and the Server application.

(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]   File "/usr/local/lib/python3.12/dist-packages/vllm/v1/worker/gpu_model_runner.py", line 3997, in execute_model
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]     deferred_state_corrections_fn = self._update_states(scheduler_output)
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]   File "/usr/local/lib/python3.12/dist-packages/vllm/v1/worker/gpu_model_runner.py", line 1239, in _update_states
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]     self._init_mrope_positions(req_state)
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]   File "/usr/local/lib/python3.12/dist-packages/vllm/v1/worker/gpu_model_runner.py", line 1582, in _init_mrope_positions
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]     assert req_state.prompt_token_ids is not None, (
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167]            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=351) ERROR 06-11 00:48:03 [core.py:1167] AssertionError: M-RoPE requires prompt_token_ids to be available.
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704] AsyncLLM output_handler failed.
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704] Traceback (most recent call last):
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704]   File "/usr/local/lib/python3.12/dist-packages/vllm/v1/engine/async_llm.py", line 660, in output_handler
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704]     outputs = await engine_core.get_output_async()
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704]               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704]   File "/usr/local/lib/python3.12/dist-packages/vllm/v1/engine/core_client.py", line 1030, in get_output_async
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704]     raise self._format_exception(outputs) from None
(APIServer pid=1) ERROR 06-11 00:48:03 [async_llm.py:704] vllm.v1.engine.exceptions.EngineDeadError: EngineCore encountered an issue. See stack trace (above) for the root cause.

All requests using the /v1/chat/completions endpoints will have
text/prompt_token_ids parts (corresponding to the chat template),
and prompt_embeds parts are handled as mm_features. This method
(rightly) filters out those prompt_embeds content parts as they
are treated as text positions.

I believe a sufficient solution to type narrowing here without
raising a fatal assertion is to instead replace the assertion
with a using dummy token ids:

def _init_mrope_positions(self, req_state: CachedRequestState):
    model = self.get_model()
    assert supports_mrope(model), "M-RoPE support is not implemented."
    mrope_model = cast(SupportsMRoPE, model)

    # Filter out prompt_embeds modality (text-only position info)
    mrope_features = [
        f for f in req_state.mm_features if f.modality != "prompt_embeds"
    ]
    
    # Handle both token_ids and embeddings-only inputs
    if req_state.prompt_token_ids is not None:
        input_tokens = req_state.prompt_token_ids
    elif req_state.prompt_embeds is not None:
        # For text-only embeddings, dummy token IDs are safe since
        # get_mrope_input_positions only uses len(input_tokens) when mm_features is empty
        seq_len = req_state.prompt_embeds.shape[0]
        input_tokens = list(range(seq_len))
        # Verify no mm_features remain (should be true after prompt_embeds filter)
        assert len(mrope_features) == 0, (
            "M-RoPE with prompt_embeds-only input should have no multimodal features"
        )
    else:
        raise ValueError(
            "M-RoPE requires either prompt_token_ids or prompt_embeds."
        )

    req_state.mrope_positions, req_state.mrope_position_delta = (
        mrope_model.get_mrope_input_positions(
            input_tokens,
            mrope_features,
        )
    )

Technically, in isolation, this method still crashes in the case
where req_state.prompt_token_ids is None and req_state.mm_features,
so the solution above still leaves that potential vector open.
Best I can tell, however, such a req_state is impossible in the
first place in online mode, because it would require a
/v1/completions request with prompt_embeds AND multimodal features,
but the /v1/completions request schema does not expose multimodal
inputs in any way that I can see. Today, those are the only two
endpoints with prompt_embeds support.

When in offline mode, I believe it is technically possible to
directly create an EngineCoreRequest that has prompt_embeds and not
prompt_token_ids and mm_features, and pass that to LLM.generate. I
believe that would trigger this same assertion, and no validation
would prevent that combination. I strongly suspect, though, that
this combination would be undefined in any model that support M-RoPE,
because it would not be possible to determine which token positions
correspond to mm_features. My proposed solution above would end up
not setting req_state.mrope_positions and
req_state.mrope_position_delta in this scenario, which could
result in undefined behavior.

I am far more familiar with prompt_embeds than I am with M-RoPE, and
I am aware that each model that supports it is responsible for
defining its own get_mrope_input_positions which have varying
implementations. I don't know enough to be prescriptive in how the
two features should interact in the offline case, other than possibly
raising a validation error earlier on preventing that combination
(which would emulate the current assertion behavior). Regardless,
in offline mode, the chances of a remote user being able to exploit
this are slim-to-nil compared to the online case which is incredibly
straightforward.


Impact

What kind of vulnerability is it? Who is impacted?

    Denial of Service caused by an incorrect assertion inside of the
GPUModelRunner which causes a fatal EngineCore exception
    Any configuration with --enable-prompt-embeds and M-RoPE-supported
model is vulnerable
    The attack is extremely easy from the remote attacker's perspective
(copying the official prompt_embeds online mode docs examples
almost-verbatim, accounting for model-name and connection details, of
course, will induce a guaranteed shutdown)


Severity
Moderate

CVE ID
CVE-2026-55514

Weaknesses
Weakness CWE-617

Credits

    @qthequartermasterman qthequartermasterman Reporter
    @jperezdealgaba jperezdealgaba Coordinator



=========================================================

+ CERT-RENATER        |    tel : 01-53-94-20-44         +
+ 23/25 Rue Daviel    |    fax : 01-53-94-20-41         +
+ 75013 Paris         |   email:cert@support.renater.fr +
=========================================================




