[Bugfix] Handle DoS Overflow Cases (#6598)

Signed-off-by: Alex Brooks <albrooks@redhat.com>
This commit is contained in:
Alex Brooks authored and GitHub committed 2026-08-25 16:09:03 +00:00
1 parent 497c537c6f
commit 0eb47b76d0
7 files changed
+175 -58

No files matched your search

@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Tests for error propagation paths within the Orchestrator.
Covers:
@@ -16,7 +16,9 @@ from types import SimpleNamespace
import janus
import pytest
from vllm.sampling_params import SamplingParams
from vllm.v1.engine.exceptions import EngineDeadError
from vllm.v1.serial_utils import MsgpackEncoder
from vllm_omni.engine.messages import (
AddCompanionRequestMessage,
@@ -46,8 +48,6 @@ pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def _sampling_params(max_tokens: int = 4):
from vllm.sampling_params import SamplingParams
return SamplingParams(max_tokens=max_tokens)
@@ -188,6 +188,45 @@ class _UnavailableDiffusionStageClient(FakeStageClient):
raise StageUnavailableError(f"stage {self.stage_id} has no live replica")
class _OverflowOnEncodeStageClient(FakeStageClient):
"""Msgpack-encodes the request's sampling params on dispatch, as the real
StageEngineCoreClient does. We use this to make sure overflow sampling params
do not break the orchestrator."""
async def add_request_async(self, request, *args, **kwargs) -> None:
MsgpackEncoder().encode(request.sampling_params)
await super().add_request_async(request, *args, **kwargs) # unreachable
@pytest.mark.asyncio
async def test_encode_overflow_should_fail_request_not_loop(orchestrator_factory) -> None:
"""Regression test for over-range seed handling."""
stage0 = _OverflowOnEncodeStageClient(stage_type="llm", final_output=True)
orchestrator_fixture = orchestrator_factory([stage0])
# seed > 2**63-1 cannot be msgpack-serialized -> the malicious input under test.
overflow_params = SamplingParams(seed=2**70)
await _enqueue_add_request(
orchestrator_fixture,
request_id="req-overflow",
prompt=SimpleNamespace(
request_id="req-overflow",
prompt_token_ids=[1, 2],
sampling_params=overflow_params,
),
original_prompt={"prompt": "hi"},
sampling_params_list=[overflow_params],
final_stage_id=0,
)
error_msg = await _wait_for_error_message(orchestrator_fixture, request_id="req-overflow")
assert error_msg.fatal is False
assert error_msg.status_code == 400
assert orchestrator_fixture.thread.is_alive()
assert "req-overflow" not in orchestrator_fixture.orchestrator.request_states
@pytest.mark.asyncio
async def test_engine_dead_error_fails_only_dead_replica_requests(orchestrator_factory) -> None:
"""Multi-replica stage: one replica dying must fail only the requests bound