Skip to content

grammar: bound recursion depth to prevent parser stack overflow (#29495) - #29755

Merged
ngxson merged 1 commit into
ggml-org:masterfrom
Hrushikesh-ramilla:fix-gbnf-recursion-depth-limit
Oct 25, 2026
Merged

ngxson merged 1 commit into
ggml-org:masterfrom
Hrushikesh-ramilla:fix-gbnf-recursion-depth-limit

Conversation

@Hrushikesh-ramilla

Copy link
Copy Markdown
Contributor

Overview

Fixes #29495.

In src/llama-grammar.cpp, llama_grammar_parser::parse_alternates and parse_sequence were mutually recursive when parsing nested groupings ( with no recursion depth bound. A client-supplied grammar payload containing deeply nested parenthesized groups or nested alternations (e.g. root ::= (((... "x" ...)))) caused unbounded call-stack consumption, leading to a stack overflow and terminating llama-server via SIGSEGV (Denial of Service).

Changes:

  1. Introduced MAX_GRAMMAR_RECURSION_DEPTH 256 in src/llama-grammar.cpp.
  2. Added depth tracking across parse_alternates and parse_sequence in src/llama-grammar.h and src/llama-grammar.cpp (defaulting to 0 for complete backward compatibility).
  3. Enforced a recursion depth check when encountering grouping (: throws std::runtime_error when depth exceeds MAX_GRAMMAR_RECURSION_DEPTH, enabling llama_grammar_parser::parse() to catch the exception, clear rules, and return false cleanly instead of crashing the process.
  4. Added a regression test in tests/test-grammar-parser.cpp verifying that deeply-nested groupings (> 256) are safely rejected.

Additional information

  • Tested against test-grammar-parser: all 20+ grammar parser test cases pass without regressions.
  • The depth limit (256) is generous for valid real-world GBNF grammars (JSON schema conversions typically stay below 30-50 levels of nesting) while preventing stack exhaustion.

Requirements

@ServeurpersoCom ServeurpersoCom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, tested on Linux against llama-server: a grammar with 50,000 nested groups segfaults on master and returns a 400 with this PR, 300 nested groups are rejected cleanly, and long chains of named rules still work. Bounding the recursion where it happens is the pattern ngxson set in #30242.

@ngxson
ngxson merged commit f1168ac into ggml-org:master Oct 25, 2026
1 check passed
auRose94 pushed a commit to auRose94/llama.cpp that referenced this pull request Oct 28, 2026
edwardyoon pushed a commit to edwardyoon/focus-llama that referenced this pull request Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: the GBNF grammar-text parser recurses without a depth limit, can cause stack-overflows and crash server (SIGSEGV)

3 participants