]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-varlink: check flags against the correct field
authorFrantisek Sumsal <frantisek@sumsal.cz>
Wed, 8 Apr 2026 14:30:54 +0000 (16:30 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 8 Apr 2026 20:33:05 +0000 (21:33 +0100)
Otherwise even a method without SD_VARLINK_SUPPORTS_MORE/REQUIRES_MORE
can emit "continues" replies without our IDL validation catching it.

src/libsystemd/sd-varlink/sd-varlink-idl.c
src/test/test-varlink-idl.c

index 22b6026a01f149f66141d13edc91c7edb03055b4..0b0ea244d6c9f4eccf966b1ac2b2b94514910a8d 100644 (file)
@@ -1955,7 +1955,7 @@ int varlink_idl_validate_method_reply(const sd_varlink_symbol *method, sd_json_v
                 return -EBADMSG;
 
         /* If method replies have the "continues" flag set, but the method is not allowed to generate that, return a recognizable error */
-        if (FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES) && (method->symbol_type & (SD_VARLINK_SUPPORTS_MORE|SD_VARLINK_REQUIRES_MORE)) == 0)
+        if (FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES) && (method->symbol_flags & (SD_VARLINK_SUPPORTS_MORE|SD_VARLINK_REQUIRES_MORE)) == 0)
                 return -EBADE;
 
         return varlink_idl_validate_symbol(method, v, SD_VARLINK_OUTPUT, reterr_bad_field);
index 0759c8292dcf3192f5bd85335127aec5c372f1cf..4b1e79c03cffda5bc28bea99bba439d6b7bef480 100644 (file)
@@ -621,4 +621,46 @@ TEST(null_map_element) {
         ASSERT_STREQ(bad_field, "m");
 }
 
+static SD_VARLINK_DEFINE_METHOD_FULL(
+                SupportsMoreMethod,
+                SD_VARLINK_SUPPORTS_MORE,
+                SD_VARLINK_DEFINE_OUTPUT(result, SD_VARLINK_STRING, 0));
+
+TEST(reply_continues_with_more_flag) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+
+        ASSERT_OK(sd_json_buildo(&v, SD_JSON_BUILD_PAIR_STRING("result", "hello")));
+
+        const char *bad_field = NULL;
+        ASSERT_OK(varlink_idl_validate_method_reply(
+                &vl_method_SupportsMoreMethod, v, SD_VARLINK_REPLY_CONTINUES, &bad_field));
+        ASSERT_NULL(bad_field);
+
+        ASSERT_OK(varlink_idl_validate_method_reply(
+                &vl_method_SupportsMoreMethod, v, /* flags= */ 0, &bad_field));
+        ASSERT_NULL(bad_field);
+}
+
+static SD_VARLINK_DEFINE_METHOD(
+                NoMoreMethod,
+                SD_VARLINK_DEFINE_OUTPUT(result, SD_VARLINK_STRING, 0));
+
+TEST(reply_continues_without_more_flag) {
+        _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+
+        ASSERT_OK(sd_json_buildo(&v, SD_JSON_BUILD_PAIR_STRING("result", "hello")));
+
+        const char *bad_field = NULL;
+        /* Request a "continues" reply from a method without SD_VARLINK_SUPPORTS_MORE/REQUIRES_MORE - this
+         * should fail the validation with EBADE */
+        ASSERT_ERROR(varlink_idl_validate_method_reply(
+                &vl_method_NoMoreMethod, v, SD_VARLINK_REPLY_CONTINUES, &bad_field), EBADE);
+        ASSERT_NULL(bad_field);
+
+        /* Without the "continues" flag, validation should succeed */
+        ASSERT_OK(varlink_idl_validate_method_reply(
+                &vl_method_NoMoreMethod, v, /* flags= */ 0, &bad_field));
+        ASSERT_NULL(bad_field);
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);