]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
json-stream: fix NULL pointer passed to memcpy on first read with INPUT_SENSITIVE main
authorLuca Boccassi <luca.boccassi@gmail.com>
Sat, 11 Apr 2026 00:41:13 +0000 (01:41 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 11 Apr 2026 04:42:28 +0000 (06:42 +0200)
When JSON_STREAM_INPUT_SENSITIVE is set before the first read,
input_buffer is NULL, input_buffer_size is 0, and input_buffer_index
is 0. The old condition '!INPUT_SENSITIVE && index == 0' would route
this case into the else branch which calls memcpy() with a NULL source
pointer, which is undefined behavior even when the length is zero, and
is caught by UBSan.

Fix by checking input_buffer_index == 0 first, then allowing the
GREEDY_REALLOC fast path also when input_buffer_size == 0, since
there is no sensitive data to protect from realloc() copying in that
case. The else branch is now only entered when there is actual data
to copy (input_buffer_size > 0), guaranteeing input_buffer is
non-NULL.

Follow-up for 6b1a59d59426cdda56648b00394addde2d454418

src/libsystemd/sd-json/json-stream.c

index d378d18a282b8a8942c11e76a3fd74bfceb40c79..e8cd2c55ddd3c4ad8fba1cea099afb972c3b9c4d 100644 (file)
@@ -1266,7 +1266,8 @@ int json_stream_read(JsonStream *s) {
 
                 add = MIN(s->buffer_max - s->input_buffer_size, s->read_chunk);
 
 
                 add = MIN(s->buffer_max - s->input_buffer_size, s->read_chunk);
 
-                if (!FLAGS_SET(s->flags, JSON_STREAM_INPUT_SENSITIVE) && s->input_buffer_index == 0) {
+                if (s->input_buffer_index == 0 &&
+                    (!FLAGS_SET(s->flags, JSON_STREAM_INPUT_SENSITIVE) || s->input_buffer_size == 0)) {
                         if (!GREEDY_REALLOC(s->input_buffer, s->input_buffer_size + add))
                                 return -ENOMEM;
                 } else {
                         if (!GREEDY_REALLOC(s->input_buffer, s->input_buffer_size + add))
                                 return -ENOMEM;
                 } else {