core: serialize API bus id and validate before deserializing bus tracks, plus several other bus util cleanups (#35970)

Follow-up for #35406
This commit is contained in:
Lennart Poettering
2025-01-14 14:39:58 +01:00
committed by GitHub
26 changed files with 190 additions and 139 deletions
+1
View File
@@ -7,6 +7,7 @@
#include "bpf-firewall.h"
#include "bpf-foreign.h"
#include "bus-get-properties.h"
#include "bus-message-util.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "cgroup.h"
+1
View File
@@ -12,6 +12,7 @@
#include "bus-common-errors.h"
#include "bus-get-properties.h"
#include "bus-log-control-api.h"
#include "bus-message-util.h"
#include "bus-util.h"
#include "chase.h"
#include "confidential-virt.h"
+29 -26
View File
@@ -5,6 +5,7 @@
#include <unistd.h>
#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;
-1
View File
@@ -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);
+7 -1
View File
@@ -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)
+9 -9
View File
@@ -1817,15 +1817,16 @@ Manager* manager_free(Manager *m) {
hashmap_free(m->uid_refs);
hashmap_free(m->gid_refs);
for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
m->prefix[dt] = mfree(m->prefix[dt]);
FOREACH_ARRAY(i, m->prefix, _EXEC_DIRECTORY_TYPE_MAX)
free(*i);
free(m->received_credentials_directory);
free(m->received_encrypted_credentials_directory);
free(m->watchdog_pretimeout_governor);
free(m->watchdog_pretimeout_governor_overridden);
m->fw_ctx = fw_ctx_free(m->fw_ctx);
fw_ctx_free(m->fw_ctx);
#if BPF_FRAMEWORK
bpf_restrict_fs_destroy(m->restrict_fs);
@@ -2142,12 +2143,6 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
/* Connect to the bus if we are good for it */
manager_setup_bus(m);
/* Now that we are connected to all possible buses, let's deserialize who is tracking us. */
r = bus_track_coldplug(m->api_bus, &m->subscribed, false, m->subscribed_as_strv);
if (r < 0)
log_warning_errno(r, "Failed to deserialized tracked clients, ignoring: %m");
m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
r = manager_varlink_init(m);
if (r < 0)
log_warning_errno(r, "Failed to set up Varlink, ignoring: %m");
@@ -3806,6 +3801,11 @@ int manager_reload(Manager *m) {
(void) manager_setup_handoff_timestamp_fd(m);
(void) manager_setup_pidref_transport_fd(m);
/* Clean up deserialized bus track information. They're never consumed during reload (as opposed to
* reexec) since we do not disconnect from the bus. */
m->subscribed_as_strv = strv_free(m->subscribed_as_strv);
m->deserialized_bus_id = SD_ID128_NULL;
/* Third, fire things up! */
manager_coldplug(m);
+7 -4
View File
@@ -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;
+1 -2
View File
@@ -117,8 +117,7 @@ int unit_serialize_state(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
if (gid_is_valid(u->ref_gid))
(void) serialize_item_format(f, "ref-gid", GID_FMT, u->ref_gid);
if (!sd_id128_is_null(u->invocation_id))
(void) serialize_item_format(f, "invocation-id", SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id));
(void) serialize_id128(f, "invocation-id", u->invocation_id);
(void) serialize_item(f, "freezer-state", freezer_state_to_string(u->freezer_state));