mirror of
https://github.com/systemd/systemd.git
synced 2026-08-12 22:17:19 +00:00
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).
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user