Repository navigation
Conversation
from_json() recursed once per nesting level of request-derived JSON (chat_template_kwargs, messages, tools) with no depth limit, so a single unauthenticated POST /v1/chat/completions carrying ~100k nested arrays overflowed the stack and SIGSEGV'd the whole server. Carry a depth counter through the recursion and throw std::runtime_error past 128 levels, which the server request path already surfaces as a 400.
|
Hi @origin-labs-ai, thanks for your contribution! Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:
Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below. |
|
There's a prior PR here with better test coverage: #31032 |
|
Thanks for the fix. #30242 covers the same crash and more: it checks the depth once at the entry, before every recursive walker, not only from_json. I tested both on master: a nested chat_template_kwargs is fixed by both, but a nested response_format schema still segfaults with this PR (it overflows in the schema builder) and returns a 400 with #30242. So I would focus on #30242. |
|
Thanks @ServeurpersoCom for testing both — agreed, #30242 is the more complete fix (entry-point depth check covering every recursive walker, including the response_format schema path this PR misses). Closing in favor of #30242. (Also thanks @nikwen for the #31032 pointer.) |
Overview
Fixes #30834
Additional information
Problem
from_json()incommon/jinja/value.cpprecursed once per nesting level of request-derived JSON (chat_template_kwargs,messages,tools) with no depth limit. A single unauthenticatedPOST /v1/chat/completionscarrying a deeply nested value overflows the stack — uncatchable SIGSEGV, whole-server crash.global_from_json()converts every top-level key unconditionally, so the crash happens during context setup even when the template never references the payload.Reproduced on master (Windows, MSVC,
stories260K.gguf,--jinja)GET /health→{"status":"ok"}POST /v1/chat/completionswithchat_template_kwargs.x= 100k nested arrays (200 KB body) → connection dropped, server process dies (stack overflow, no log output)GET /health→ connection refusedFix
Carry a depth counter through the
from_jsonrecursion and throwstd::runtime_errorpast 128 levels (generous — real chat contexts are a handful of levels deep):After the fix, the same request returns cleanly and the server stays up:
{"error":{"code":400,"message":"Unable to generate parser for this template. Automatic parser generation failed: JSON nesting depth exceeds 128","type":"invalid_request_error"}}GET /health→{"status":"ok"}, normalPOST /v1/chat/completionsstill returns 200.Note: the same request body could in principle also stress
nlohmann::json::parseof the raw HTTP body; that path survived the depth used here (the crash was infrom_json), but if maintainers want a hard cap on body-parse nesting too, that would be a separate guard at the HTTP boundary.Requirements