From 9fe8faffe58a1255766b076d55a3f78a3128bf3a Mon Sep 17 00:00:00 2001 From: Luigi Colluto Date: Sat, 11 Jul 2026 18:57:05 +0200 Subject: [PATCH] Fix double-free in JSON request parser (null *out on failure) json_string() returns false on a non-string or malformed value without writing *out. Several callers reparse in place with `free(x); json_string(&p, &x)` -- the "model" field in parse_chat_request / parse_completion_request / parse_anthropic_request, and duplicate JSON keys for type/name/description across the tool-schema and message parsers. On a failed reparse, *out keeps the just-freed pointer; the request's cleanup (request_free) then frees it again. This is reachable pre-auth with a single request, e.g. POST /v1/chat/completions {"messages":[...],"model":0} Initialize *out = NULL at the top of json_string so every failure path leaves the caller's pointer defined, closing all the free-then-reparse sites at the root rather than patching each call site. The success path is unchanged (*out is still set by buf_take). --- ds4_server.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ds4_server.c b/ds4_server.c index 34a9d5084..3afc89746 100644 --- a/ds4_server.c +++ b/ds4_server.c @@ -219,6 +219,13 @@ static bool json_u16(const char **p, uint32_t *out) { } static bool json_string(const char **p, char **out) { + /* Always define *out. Every failure path below returns false without + * producing a string, and several callers reparse in place with + * `free(x); json_string(&p, &x)` (e.g. duplicate JSON keys, the "model" + * field). Without this, a non-string or malformed value leaves *out + * holding the just-freed pointer, which a later cleanup frees again -- + * a double-free. Nulling on entry closes that whole class at the root. */ + *out = NULL; json_ws(p); if (**p != '"') return false; (*p)++;