From: Mike Yuan Date: Mon, 13 Jan 2025 16:06:35 +0000 (+0100) Subject: core: serialize API bus id and validate before deserializing bus tracks X-Git-Tag: v258-rc1~1622^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1446e3c3921067e3a6228a3e172b5dfd95437136;p=thirdparty%2Fsystemd.git core: serialize API bus id and validate before deserializing bus tracks --- diff --git a/TODO b/TODO index c796b3e1011..fdd119434e0 100644 --- a/TODO +++ b/TODO @@ -131,11 +131,6 @@ Features: * in pid1: include ExecStart= cmdlines (and other Exec*= cmdlines) in polkit request, so that policies can match against command lines. -* in pid1: before processing subscribed_as_strv when we come back from a - bus disconnect, let's check the bus 128bit id reported by the bus driver: if - it doesn't equal the one from before we should skip reinstalling the bus - tracker objects. - * account number of units currently in activating/active/deactivating state in each slice, and expose this as a property of the slice, given this is a key metric of the resource management entity that a slice is. (maybe add a 2nd diff --git a/src/core/dbus.c b/src/core/dbus.c index 58cd1ee175b..a2a2611a03e 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -5,6 +5,7 @@ #include #include "sd-bus.h" +#include "sd-id128.h" #include "alloc-util.h" #include "bus-common-errors.h" @@ -774,6 +775,24 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } +static int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, char * const *l) { + int r; + + assert(bus); + assert(t); + + if (strv_isempty(l)) + return 0; + + if (!*t) { + r = sd_bus_track_new(bus, t, NULL, NULL); + if (r < 0) + return r; + } + + return bus_track_add_name_many(*t, l); +} + static int bus_setup_api(Manager *m, sd_bus *bus) { char *name; Unit *u; @@ -860,10 +879,15 @@ int bus_init_api(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to set up API bus: %m"); - (void) bus_track_coldplug(bus, &m->subscribed, /* recursive= */ false, m->subscribed_as_strv); + r = bus_get_instance_id(bus, &m->bus_id); + if (r < 0) + log_warning_errno(r, "Failed to query API bus instance ID, not deserializing subscriptions: %m"); + else if (sd_id128_is_null(m->deserialized_bus_id) || sd_id128_equal(m->bus_id, m->deserialized_bus_id)) + (void) bus_track_coldplug(bus, &m->subscribed, m->subscribed_as_strv); m->subscribed_as_strv = strv_free(m->subscribed_as_strv); - m->api_bus = TAKE_PTR(bus); + m->deserialized_bus_id = SD_ID128_NULL; + m->api_bus = TAKE_PTR(bus); return 0; } @@ -1015,6 +1039,9 @@ static void destroy_bus(Manager *m, sd_bus **bus) { log_warning_errno(r, "Failed to serialize api subscribers, ignoring: %m"); strv_free_and_replace(m->subscribed_as_strv, subscribed); + m->deserialized_bus_id = m->bus_id; + m->bus_id = SD_ID128_NULL; + m->subscribed = sd_bus_track_unref(m->subscribed); } @@ -1163,30 +1190,6 @@ void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) { } } -int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l) { - int r; - - assert(t); - - if (strv_isempty(l)) - return 0; - - if (!bus) - return 0; - - if (!*t) { - r = sd_bus_track_new(bus, t, NULL, NULL); - if (r < 0) - return r; - } - - r = sd_bus_track_set_recursive(*t, recursive); - if (r < 0) - return r; - - return bus_track_add_name_many(*t, l); -} - uint64_t manager_bus_n_queued_write(Manager *m) { uint64_t c = 0; sd_bus *b; diff --git a/src/core/dbus.h b/src/core/dbus.h index eb1baf60493..0f81102fc13 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -19,7 +19,6 @@ void bus_done(Manager *m); int bus_fdset_add_all(Manager *m, FDSet *fds); void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix); -int bus_track_coldplug(sd_bus *bus, sd_bus_track **t, bool recursive, char **l); int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata); diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c index 4aecb6de2f6..fbc1475bcf5 100644 --- a/src/core/manager-serialize.c +++ b/src/core/manager-serialize.c @@ -158,6 +158,7 @@ int manager_serialize( (void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit); (void) serialize_ratelimit(f, "reload-reexec-ratelimit", &m->reload_reexec_ratelimit); + (void) serialize_id128(f, "bus-id", m->bus_id); bus_track_serialize(m->subscribed, f, "subscribed"); r = dynamic_user_serialize(m, f, fds); @@ -487,7 +488,12 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { manager_deserialize_gid_refs_one(m, val); else if ((val = startswith(l, "exec-runtime="))) (void) exec_shared_runtime_deserialize_one(m, val, fds); - else if ((val = startswith(l, "subscribed="))) { + else if ((val = startswith(l, "bus-id="))) { + + r = sd_id128_from_string(val, &m->deserialized_bus_id); + if (r < 0) + return r; + } else if ((val = startswith(l, "subscribed="))) { r = strv_extend(&m->subscribed_as_strv, val); if (r < 0) diff --git a/src/core/manager.h b/src/core/manager.h index 7016eab2d3b..c5bd242968a 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -335,13 +335,16 @@ struct Manager { int private_listen_fd; sd_event_source *private_listen_event_source; - /* Contains all the clients that are subscribed to signals via - the API bus. Note that private bus connections are always - considered subscribes, since they last for very short only, - and it is much simpler that way. */ + /* Contains all the clients that are subscribed to signals via the API bus. Note that private bus + * connections are always considered subscribes, since they last for very short only, and it is + * much simpler that way. */ sd_bus_track *subscribed; char **subscribed_as_strv; + /* The bus id of API bus acquired through org.freedesktop.DBus.GetId, which before deserializing + * subscriptions we'd use to verify the bus is still the same instance as before. */ + sd_id128_t bus_id, deserialized_bus_id; + /* This is used during reloading: before the reload we queue * the reply message here, and afterwards we send it */ sd_bus_message *pending_reload_message; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 0a887aec792..05926771d26 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -686,7 +686,7 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send return 1; } -int bus_track_add_name_many(sd_bus_track *t, char **l) { +int bus_track_add_name_many(sd_bus_track *t, char * const *l) { int r = 0; assert(t); diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index 5fb4bcca9fa..63c3ba5ee3b 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -65,7 +65,7 @@ static inline int bus_log_connect_error(int r, BusTransport transport, RuntimeSc int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path); int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external); -int bus_track_add_name_many(sd_bus_track *t, char **l); +int bus_track_add_name_many(sd_bus_track *t, char * const *l); int bus_track_to_strv(sd_bus_track *t, char ***ret); int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *description);