bus-map-properties: reject wrong variant type

bus_message_map_all_properties() fed the peer-supplied wire signature straight
into the variant dispatch and never compared it against the declared
prop->signature, so map_basic() wrote at the wire type's native width into a
slot sized for the declared type (over-wide numeric writes, peer-controlled
pointers into char** slots later freed by strv_free()). Compare against
prop->signature and skip the variant on mismatch.

This is in practice not a problem as the servers are trusted, and this
only affects clients.

Follow-up for 9f6eb1cd58

Assisted-by: kres (claude-opus-4-7)
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luca Boccassi
2026-06-11 09:43:09 +02:00
committed by Daan De Meyer
parent 0aaba6eb83
commit 39bc1dfa0f
2 changed files with 195 additions and 13 deletions
+21 -13
View File
@@ -173,21 +173,29 @@ int bus_message_map_all_properties(
if (r < 0)
return bus_log_parse_error_debug(r);
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
if (r < 0)
return bus_log_parse_error_debug(r);
if (prop->signature && !streq(contents, prop->signature)) {
log_debug("Unexpected type for property '%s': expected '%s', got '%s', ignoring.",
member, prop->signature, contents);
r = sd_bus_message_skip(m, "v");
if (r < 0)
return bus_log_parse_error_debug(r);
} else {
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
if (r < 0)
return bus_log_parse_error_debug(r);
v = (uint8_t *)userdata + prop->offset;
if (map[i].set)
r = prop->set(sd_bus_message_get_bus(m), member, m, reterr_error, v);
else
r = map_basic(m, flags, v);
if (r < 0)
return bus_log_parse_error_debug(r);
v = (uint8_t*) userdata + prop->offset;
if (prop->set)
r = prop->set(sd_bus_message_get_bus(m), member, m, reterr_error, v);
else
r = map_basic(m, flags, v);
if (r < 0)
return bus_log_parse_error_debug(r);
r = sd_bus_message_exit_container(m);
if (r < 0)
return bus_log_parse_error_debug(r);
r = sd_bus_message_exit_container(m);
if (r < 0)
return bus_log_parse_error_debug(r);
}
} else {
r = sd_bus_message_skip(m, "v");
if (r < 0)