summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-12-09 20:08:33 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-12-10 10:43:14 +0100
commit29f63c67b01f8db9f088daa5d25b345cc697688d (patch)
tree913f28b881a5f4a938051a872fb67d33cb32a08e
parentjournalctl: show coredumps again when --unit= is specified (diff)
downloadsystemd-29f63c67b01f8db9f088daa5d25b345cc697688d.tar.xz
systemd-29f63c67b01f8db9f088daa5d25b345cc697688d.zip
sd-varlink: add sd_varlink_server_set_info
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.
-rw-r--r--src/fuzz/fuzz-varlink.c1
-rw-r--r--src/libsystemd/libsystemd.sym1
-rw-r--r--src/libsystemd/sd-varlink/sd-varlink.c46
-rw-r--r--src/libsystemd/sd-varlink/varlink-internal.h5
-rw-r--r--src/systemd/sd-varlink.h7
5 files changed, 49 insertions, 11 deletions
diff --git a/src/fuzz/fuzz-varlink.c b/src/fuzz/fuzz-varlink.c
index 2342e34d8f..2497fe3b9e 100644
--- a/src/fuzz/fuzz-varlink.c
+++ b/src/fuzz/fuzz-varlink.c
@@ -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);
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 0b948b86a2..a76dc7e4ae 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -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;
diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c
index 150ce4edda..5e9999deaf 100644
--- a/src/libsystemd/sd-varlink/sd-varlink.c
+++ b/src/libsystemd/sd-varlink/sd-varlink.c
@@ -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;
diff --git a/src/libsystemd/sd-varlink/varlink-internal.h b/src/libsystemd/sd-varlink/varlink-internal.h
index b184ac7754..377f8cfae4 100644
--- a/src/libsystemd/sd-varlink/varlink-internal.h
+++ b/src/libsystemd/sd-varlink/varlink-internal.h
@@ -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;
diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h
index fbf575ffdf..833977d8b2 100644
--- a/src/systemd/sd-varlink.h
+++ b/src/systemd/sd-varlink.h
@@ -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);