From: Frantisek Sumsal Date: Fri, 20 Mar 2026 19:27:07 +0000 (+0100) Subject: sd-varlink: gracefully reject arrays/maps with a null element X-Git-Tag: v261-rc1~773 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=924f5a3461512ac8126fe4423329e3ca802b4d20;p=thirdparty%2Fsystemd.git sd-varlink: gracefully reject arrays/maps with a null element Follow-up for 799392286ec0797c0a2a1260c444360b47ef36fc. --- diff --git a/src/libsystemd/sd-varlink/sd-varlink-idl.c b/src/libsystemd/sd-varlink/sd-varlink-idl.c index a70cbe529ce..144450b702d 100644 --- a/src/libsystemd/sd-varlink/sd-varlink-idl.c +++ b/src/libsystemd/sd-varlink/sd-varlink-idl.c @@ -1705,7 +1705,12 @@ static int varlink_idl_validate_symbol(const sd_varlink_symbol *symbol, sd_json_ static int varlink_idl_validate_field_element_type(const sd_varlink_field *field, sd_json_variant *v) { assert(field); assert(v); - assert(!sd_json_variant_is_null(v)); + + if (sd_json_variant_is_null(v)) + return varlink_idl_log( + SYNTHETIC_ERRNO(EMEDIUMTYPE), + "Field '%s' element is null, refusing.", + strna(field->name)); switch (field->field_type) { @@ -1767,7 +1772,7 @@ static int varlink_idl_validate_field_element_type(const sd_varlink_field *field case SD_VARLINK_ANY: /* The any type accepts any non-null JSON value, no validation needed. (Note that null is - * already handled by the caller.) */ + * already gracefully rejected at the start of this function.) */ break; case _SD_VARLINK_FIELD_COMMENT: diff --git a/src/test/test-varlink-idl.c b/src/test/test-varlink-idl.c index 039d36a85e4..469bf8c2fe0 100644 --- a/src/test/test-varlink-idl.c +++ b/src/test/test-varlink-idl.c @@ -581,4 +581,42 @@ TEST(any) { ASSERT_NULL(bad_field); } +static SD_VARLINK_DEFINE_METHOD( + ArrayTest, + SD_VARLINK_DEFINE_INPUT(arr, SD_VARLINK_INT, SD_VARLINK_ARRAY)); + +static SD_VARLINK_DEFINE_METHOD( + MapTest, + SD_VARLINK_DEFINE_INPUT(m, SD_VARLINK_STRING, SD_VARLINK_MAP)); + +TEST(null_array_element) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + + /* Build an array with a null element - this should be rejected gracefully, not crash */ + ASSERT_OK(sd_json_buildo(&v, + SD_JSON_BUILD_PAIR("arr", SD_JSON_BUILD_ARRAY( + SD_JSON_BUILD_INTEGER(1), + SD_JSON_BUILD_NULL, + SD_JSON_BUILD_INTEGER(3))))); + + const char *bad_field = NULL; + ASSERT_ERROR(varlink_idl_validate_method_call(&vl_method_ArrayTest, v, /* flags= */ 0, &bad_field), EMEDIUMTYPE); + ASSERT_STREQ(bad_field, "arr"); +} + +TEST(null_map_element) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + + /* Build a map with a null value - this should be rejected gracefully, not crash */ + ASSERT_OK(sd_json_buildo(&v, + SD_JSON_BUILD_PAIR("m", SD_JSON_BUILD_OBJECT( + SD_JSON_BUILD_PAIR_STRING("key1", "value1"), + SD_JSON_BUILD_PAIR_NULL("key2"), + SD_JSON_BUILD_PAIR_STRING("key3", "value3"))))); + + const char *bad_field = NULL; + ASSERT_ERROR(varlink_idl_validate_method_call(&vl_method_MapTest, v, /* flags= */ 0, &bad_field), EMEDIUMTYPE); + ASSERT_STREQ(bad_field, "m"); +} + DEFINE_TEST_MAIN(LOG_DEBUG);