From 9b21738498affe2b7ec477be1b55e79a052d852f Mon Sep 17 00:00:00 2001 From: TristanInSec Date: Tue, 19 May 2026 17:33:06 -0400 Subject: [PATCH] sd-bus: add depth limit to message_skip_fields() to prevent stack overflow message_skip_fields() recurses for each nested variant ('v') type in D-Bus message header fields. A crafted message with deeply nested variants (e.g., a variant containing a variant containing a variant...) causes unbounded stack growth, leading to stack overflow and crash. Add a depth parameter that increments on each recursive call and rejects messages exceeding BUS_CONTAINER_DEPTH with -EBADMSG. This matches the existing depth limits enforced elsewhere in the sd-bus message processing (e.g., bus_message_enter_container). --- src/libsystemd/sd-bus/bus-message.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index 017ffb7a612..a719253fa73 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -3904,7 +3904,8 @@ static int message_skip_fields( sd_bus_message *m, size_t *ri, uint32_t array_size, - const char **signature) { + const char **signature, + unsigned depth) { size_t original_index; int r; @@ -3913,6 +3914,9 @@ static int message_skip_fields( assert(ri); assert(signature); + if (depth >= BUS_CONTAINER_DEPTH) + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Maximum container nesting depth reached, refusing."); + original_index = *ri; for (;;) { @@ -3993,7 +3997,7 @@ static int message_skip_fields( if (r < 0) return r; - r = message_skip_fields(m, ri, nas, (const char**) &s); + r = message_skip_fields(m, ri, nas, (const char**) &s, depth + 1); if (r < 0) return r; } @@ -4007,7 +4011,7 @@ static int message_skip_fields( if (r < 0) return r; - r = message_skip_fields(m, ri, UINT32_MAX, &s); + r = message_skip_fields(m, ri, UINT32_MAX, &s, depth + 1); if (r < 0) return r; @@ -4025,7 +4029,7 @@ static int message_skip_fields( strncpy(sig, *signature + 1, l); sig[l] = '\0'; - r = message_skip_fields(m, ri, UINT32_MAX, (const char**) &s); + r = message_skip_fields(m, ri, UINT32_MAX, (const char**) &s, depth + 1); if (r < 0) return r; } @@ -4198,7 +4202,7 @@ static int message_parse_fields(sd_bus_message *m, bool got_ctrunc) { break; default: - r = message_skip_fields(m, &ri, UINT32_MAX, &signature); + r = message_skip_fields(m, &ri, UINT32_MAX, &signature, 0); } if (r < 0) return r; -- 2.47.3