Skip to content

[Security] Centralize grammar compilation timeout at scheduler level - #45172

Open
jperezdealgaba wants to merge 2 commits into
vllm-project:mainfrom
jperezdealgaba:fix/structured-output-compilation-timeout
Open

jperezdealgaba wants to merge 2 commits into
vllm-project:mainfrom
jperezdealgaba:fix/structured-output-compilation-timeout

Conversation

@jperezdealgaba

Copy link
Copy Markdown
Contributor

Introduce compile_with_timeout() and wrap every grammar/schema/regex compilation call in xgrammar, outlines, and llguidance backends. Adversarial JSON schemas (recursive $ref, deeply nested oneOf/anyOf), regex patterns, and EBNF grammars can cause exponential DFA state-space explosion that hangs the inference worker indefinitely.

Covered call sites:

  • xgrammar: compile_json_schema, compile_grammar, compile_regex, compile_structural_tag, and validation pre-flights
  • outlines: build_regex_from_schema, oc.Index
  • llguidance: grammar_from_json_schema Configurable via VLLM_STRUCTURED_OUTPUT_COMPILATION_TIMEOUT_S (default 5s, set to 0 to disable).

Comment thread vllm/v1/structured_output/utils.py Resolved
@mergify

mergify Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @jperezdealgaba.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Jun 13, 2026
@jperezdealgaba
jperezdealgaba force-pushed the fix/structured-output-compilation-timeout branch from 9cf912d to eb0b75c Compare June 13, 2026 10:40
@mergify mergify Bot removed the needs-rebase label Jun 13, 2026
Add upper-bound validation at the SamplingParams._verify_args()
chokepoint for logit_bias, bad_words, stop_token_ids, and
allowed_token_ids. All limits are user-configurable via environment
variables so operators can override when their workload legitimately
exceeds the defaults:

- VLLM_MAX_LOGIT_BIAS_SIZE (default: 0 = vocab_size ceiling)
- VLLM_MAX_ALLOWED_TOKEN_IDS (default: 0 = vocab_size ceiling)
- VLLM_MAX_STOP_TOKEN_IDS (default: 128)
- VLLM_MAX_BAD_WORDS (default: 1000)
- VLLM_MAX_BAD_WORD_LENGTH (default: 1000)
- VLLM_MAX_BATCH_CONVERSATIONS (default: 1000)

For logit_bias and allowed_token_ids the natural ceiling is
vocab_size, enforced at verify() time when model_config is available.
The env var overrides can tighten this further.

Batch chat completions messages list is bounded at the protocol layer
(VLLM_MAX_BATCH_CONVERSATIONS) since it has no SamplingParams
equivalent.

Addresses GHSA-4fv6-24cq-h5pw, GHSA-m9fh-2f8w-jhw9,
GHSA-83mh-6mwq-3hg9, and GHSA-rp22-rc8r-qjmh.

Signed-off-by: Juan Pérez de Algaba <jperezde@redhat.com>

Signed-off-by: jperezde <jperezde@redhat.com>
Replace per-backend run_with_timeout() + semaphore approach with a
centralized deadline check at the scheduler's existing promotion poll
point. This addresses multiple issues with the previous design:

- 4 hung requests permanently exhausted the semaphore, disabling
  structured output until restart (makes DoS easier to trigger)
- Semaphore throttled legitimate traffic (performance regression)
- Per-backend wrapping was scattered and hard to maintain

New approach:
- Record compilation_start_time in StructuredOutputRequest when
  grammar_init() starts compilation
- Scheduler checks elapsed time at the WAITING_FOR_GRAMMAR promotion
  point; if exceeded, fail the request (not the engine)
- Fix _check_grammar_completion to catch ALL exceptions from the
  Future, not just TimeoutError; store as compile_error and let the
  scheduler fail the request gracefully
- Slim frontend validation to cheap checks only (JSON parsing, schema
  feature detection, regex buildability, string conversions); let the
  engine-side compile be the authority

The existing bounded ThreadPoolExecutor (cpu_count//2 workers) already
provides natural concurrency control for compilation jobs.

The compile_regex_with_timeout from PR vllm-project#45118 is preserved as a
complementary ReDoS-specific guard for regex patterns.

Adds compilation_timeout config field to StructuredOutputsConfig
(default: 10s, set to 0 to disable).

Addresses GHSA-q9q8-922v-2c42 and GHSA-29wg-4hmv-h32g.

Signed-off-by: Juan Pérez de Algaba <jperezde@redhat.com>

Signed-off-by: jperezde <jperezde@redhat.com>
@mergify mergify Bot added the frontend label Jun 14, 2026
@jperezdealgaba jperezdealgaba changed the title [Security] Add timeout guard for all structured output compilation paths [Security] Centralize grammar compilation timeout at scheduler level Jun 14, 2026
@mergify

mergify Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @jperezdealgaba.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant