]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-varlink: add sd_varlink_server_set_info
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 9 Dec 2024 19:08:33 +0000 (20:08 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 Dec 2024 09:43:14 +0000 (10:43 +0100)
Fixes https://github.com/systemd/systemd/issues/35508.

As reported in the bug, the values were hardcoded for the systemd project.
https://varlink.org/Service lists vendor, product, version, url, and interfaces
as the mandatory parameters, so add an interface to set the first four. The
last field is set automatically based on the registered interfaces as before.

If the values are not filled in, we return empty strings. With NULL,
'varlinkctl info' would say:
  (string):1:25: Object field 'vendor' has wrong type null, expected string.

src/fuzz/fuzz-varlink.c
src/libsystemd/libsystemd.sym
src/libsystemd/sd-varlink/sd-varlink.c
src/libsystemd/sd-varlink/varlink-internal.h
src/systemd/sd-varlink.h

index 2342e34d8f77c71070516230294b43ec9c5355db..2497fe3b9e741c05541fb46a9de8d812b992a2a5 100644 (file)
@@ -102,6 +102,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         /* Test one: write the data as method call to a server */
         assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, server_pair) >= 0);
         assert_se(sd_varlink_server_new(&s, 0) >= 0);
+        assert_se(sd_varlink_server_set_info(s, "Vendor", "Product", "Version", "URL") >= 0);
         assert_se(sd_varlink_server_set_description(s, "myserver") >= 0);
         assert_se(sd_varlink_server_attach_event(s, e, 0) >= 0);
         assert_se(sd_varlink_server_add_connection(s, server_pair[0], NULL) >= 0);
index 0b948b86a2be5b91152f1a20bd893e09db606d13..a76dc7e4ae0058dc1e9c97aa8d2fe11bfa309e40 100644 (file)
@@ -1037,6 +1037,7 @@ global:
         sd_varlink_server_set_connections_max;
         sd_varlink_server_set_connections_per_uid_max;
         sd_varlink_server_set_description;
+        sd_varlink_server_set_info;
         sd_varlink_server_set_exit_on_idle;
         sd_varlink_server_set_userdata;
         sd_varlink_server_shutdown;
index 150ce4eddabc8f68cf794a60e34a41bf7dd2eb9d..5e9999deafd26dc281b43f62c3abeb840cc99208 100644 (file)
@@ -31,7 +31,6 @@
 #include "varlink-internal.h"
 #include "varlink-io.systemd.h"
 #include "varlink-org.varlink.service.h"
-#include "version.h"
 
 #define VARLINK_DEFAULT_CONNECTIONS_MAX 4096U
 #define VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX 1024U
@@ -1193,20 +1192,16 @@ static int generic_method_get_info(
                 void *userdata) {
 
         _cleanup_strv_free_ char **interfaces = NULL;
-        _cleanup_free_ char *product = NULL;
         int r;
 
         assert(link);
+        assert(link->server);
 
         if (sd_json_variant_elements(parameters) != 0)
                 return sd_varlink_error_invalid_parameter(link, parameters);
 
-        product = strjoin("systemd (", program_invocation_short_name, ")");
-        if (!product)
-                return -ENOMEM;
-
         sd_varlink_interface *interface;
-        HASHMAP_FOREACH(interface, ASSERT_PTR(link->server)->interfaces) {
+        HASHMAP_FOREACH(interface, link->server->interfaces) {
                 r = strv_extend(&interfaces, interface->name);
                 if (r < 0)
                         return r;
@@ -1216,10 +1211,10 @@ static int generic_method_get_info(
 
         return sd_varlink_replybo(
                         link,
-                        SD_JSON_BUILD_PAIR_STRING("vendor", "The systemd Project"),
-                        SD_JSON_BUILD_PAIR_STRING("product", product),
-                        SD_JSON_BUILD_PAIR_STRING("version", PROJECT_VERSION_FULL " (" GIT_VERSION ")"),
-                        SD_JSON_BUILD_PAIR_STRING("url", "https://systemd.io/"),
+                        SD_JSON_BUILD_PAIR_STRING("vendor", strempty(link->server->vendor)),
+                        SD_JSON_BUILD_PAIR_STRING("product", strempty(link->server->product)),
+                        SD_JSON_BUILD_PAIR_STRING("version", strempty(link->server->version)),
+                        SD_JSON_BUILD_PAIR_STRING("url", strempty(link->server->url)),
                         SD_JSON_BUILD_PAIR_STRV("interfaces", interfaces));
 }
 
@@ -3262,12 +3257,41 @@ static sd_varlink_server* varlink_server_destroy(sd_varlink_server *s) {
         sd_event_unref(s->event);
 
         free(s->description);
+        free(s->vendor);
+        free(s->product);
+        free(s->version);
+        free(s->url);
 
         return mfree(s);
 }
 
 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_varlink_server, sd_varlink_server, varlink_server_destroy);
 
+_public_ int sd_varlink_server_set_info(
+                sd_varlink_server *s,
+                const char *vendor,
+                const char *product,
+                const char *version,
+                const char *url) {
+
+        assert_return(s, -EINVAL);
+
+        _cleanup_free_ char
+                *a = vendor ? strdup(vendor) : NULL,
+                *b = product ? strdup(product) : NULL,
+                *c = version ? strdup(version) : NULL,
+                *d = url ? strdup(url) : NULL;
+        if ((vendor && !a) || (product && !b) || (version && !c) || (url && !d))
+                return log_oom_debug();
+
+        free_and_replace(s->vendor, a);
+        free_and_replace(s->product, b);
+        free_and_replace(s->version, c);
+        free_and_replace(s->url, d);
+
+        return 0;
+}
+
 static int validate_connection(sd_varlink_server *server, const struct ucred *ucred) {
         int allowed = -1;
 
index b184ac77546c945b3a06564515904797268663eb..377f8cfae4511f7e3e5d9a00fc9912a025c4d049 100644 (file)
@@ -222,7 +222,12 @@ struct sd_varlink_server {
         Hashmap *by_uid;               /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */
 
         void *userdata;
+
         char *description;
+        char *vendor;
+        char *product;
+        char *version;
+        char *url;
 
         unsigned connections_max;
         unsigned connections_per_uid_max;
index fbf575ffdf63ae87847a6afe7f59159e26b8b52b..833977d8b206159143966a8d4a80225030e0065f 100644 (file)
@@ -219,6 +219,13 @@ int sd_varlink_server_new(sd_varlink_server **ret, sd_varlink_server_flags_t fla
 sd_varlink_server* sd_varlink_server_ref(sd_varlink_server *s);
 sd_varlink_server* sd_varlink_server_unref(sd_varlink_server *s);
 
+int sd_varlink_server_set_info(
+                sd_varlink_server *s,
+                const char *vendor,
+                const char *product,
+                const char *version,
+                const char *url);
+
 /* Add addresses or fds to listen on */
 int sd_varlink_server_listen_address(sd_varlink_server *s, const char *address, mode_t mode);
 int sd_varlink_server_listen_fd(sd_varlink_server *s, int fd);