X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=a7d18e337b874244b97cccfc9348ffa10c68f74d;hp=ef157d69f2eb6bea061450ee8ee0b1cc7591139a;hb=412c18f10c9df3f0a02358d8c0e707ed2e5fa186;hpb=7fa934b0d35492b300b79848f4822ffc40eee21f diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index ef157d69f..a7d18e337 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -32,6 +32,8 @@ #include "util.h" #include "strv.h" #include "memfd-util.h" +#include "cgroup-util.h" +#include "fileio.h" #include "bus-internal.h" #include "bus-message.h" @@ -39,7 +41,6 @@ #include "bus-bloom.h" #include "bus-util.h" #include "bus-label.h" -#include "cgroup-util.h" #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -348,6 +349,15 @@ fail: return r; } +static void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) { + assert(bus); + assert(m); + + m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus"; + m->creds.well_known_names_driver = true; + m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask; +} + static void unset_memfds(struct sd_bus_message *m) { struct bus_body_part *part; unsigned i; @@ -660,9 +670,23 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { } if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) { - r = strv_extend(&m->creds.well_known_names, d->name.name); - if (r < 0) + char **wkn; + size_t n; + + /* We just extend the array here, but + * do not allocate the strings inside + * of it, instead we just point to our + * buffer directly. */ + n = strv_length(m->creds.well_known_names); + wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*)); + if (!wkn) { + r = -ENOMEM; goto fail; + } + + wkn[n] = d->name.name; + wkn[n+1] = NULL; + m->creds.well_known_names = wkn; m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES; } @@ -694,6 +718,14 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { } } + /* If we requested the list of well-known names to be appended + * and the sender had none no item for it will be + * attached. However, this does *not* mean that we the kernel + * didn't want to provide this information to us. Hence, let's + * explicitly mark this information as available if it was + * requested. */ + m->creds.mask |= bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES; + r = bus_message_parse_fields(m); if (r < 0) goto fail; @@ -724,7 +756,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { /* Override information from the user header with data from the kernel */ if (k->src_id == KDBUS_SRC_ID_KERNEL) - m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus"; + bus_message_set_sender_driver(bus, m); else { snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id); m->sender = m->creds.unique_name = m->sender_buffer; @@ -1059,7 +1091,7 @@ static int push_name_owner_changed(sd_bus *bus, const char *name, const char *ol if (r < 0) return r; - m->sender = "org.freedesktop.DBus"; + bus_message_set_sender_driver(bus, m); r = bus_seal_synthetic_message(bus, m); if (r < 0) @@ -1128,7 +1160,7 @@ static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item * if (r < 0) return r; - m->sender = "org.freedesktop.DBus"; + bus_message_set_sender_driver(bus, m); r = bus_seal_synthetic_message(bus, m); if (r < 0) @@ -1765,3 +1797,40 @@ int bus_kernel_realize_attach_flags(sd_bus *bus) { return 0; } + +int bus_kernel_fix_attach_mask(void) { + _cleanup_free_ char *mask = NULL; + uint64_t m = (uint64_t) -1; + char buf[2+16+2]; + int r; + + /* By default we don't want any kdbus metadata fields to be + * suppressed, hence we reset the kernel mask for it to + * (uint64_t) -1. This is overridable via a kernel command + * line option, however. */ + + r = get_proc_cmdline_key("systemd.kdbus_attach_flags_mask=", &mask); + if (r < 0) { + log_warning_errno(-r, "Failed to read kernel command line: %m"); + return r; + } + + if (mask) { + const char *p = mask; + + if (startswith(p, "0x")) + p += 2; + + if (sscanf(p, "%" PRIx64, &m) != 1) + log_warning("Couldn't parse systemd.kdbus_attach_flags_mask= kernel command line parameter."); + } + + sprintf(buf, "0x%" PRIx64 "\n", m); + r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf); + if (r < 0) { + log_warning_errno(-r, "Failed to write kdbus attach mask: %m"); + return r; + } + + return 0; +}