X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=7c946e61c2481cc81882b3b1c51212b17c8361d7;hb=d29ae2914e1146f45ff4104faafef5331837bed7;hp=a7811eea0a10fc55f81e8337f108f7a718f67c99;hpb=3c70e3bb022f0de3317f3600c9366a2f4597339e;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index a7811eea0..7c946e61c 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -32,6 +32,7 @@ #include "util.h" #include "strv.h" #include "memfd-util.h" +#include "capability.h" #include "cgroup-util.h" #include "fileio.h" @@ -295,7 +296,8 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { m->kdbus->flags = ((m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) ? 0 : KDBUS_MSG_EXPECT_REPLY) | - ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0); + ((m->header->flags & BUS_MESSAGE_NO_AUTO_START) ? KDBUS_MSG_NO_AUTO_START : 0) | + ((m->header->type == SD_BUS_MESSAGE_SIGNAL) ? KDBUS_MSG_SIGNAL : 0); if (well_known) /* verify_destination_id will usually be 0, which makes the kernel driver only look @@ -377,15 +379,6 @@ 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; @@ -398,6 +391,21 @@ static void unset_memfds(struct sd_bus_message *m) { part->memfd = -1; } +static void message_set_timestamp(sd_bus *bus, sd_bus_message *m, const struct kdbus_timestamp *ts) { + assert(bus); + assert(m); + + if (!ts) + return; + + if (!(bus->attach_flags & KDBUS_ATTACH_TIMESTAMP)) + return; + + m->realtime = ts->realtime_ns / NSEC_PER_USEC; + m->monotonic = ts->monotonic_ns / NSEC_PER_USEC; + m->seqnum = ts->seqnum; +} + static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { sd_bus_message *m = NULL; struct kdbus_item *d; @@ -618,13 +626,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { break; case KDBUS_ITEM_TIMESTAMP: - - if (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) { - m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC; - m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC; - m->seqnum = d->timestamp.seqnum; - } - + message_set_timestamp(bus, m, &d->timestamp); break; case KDBUS_ITEM_PID_COMM: @@ -673,8 +675,13 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { break; case KDBUS_ITEM_CAPS: - m->creds.capability = (uint8_t *) d->caps.caps; - m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps); + if (d->caps.last_cap != cap_last_cap() || + d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) { + r = -EBADMSG; + goto fail; + } + + m->creds.capability = d->caps.caps; m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask; break; @@ -744,7 +751,7 @@ 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 + * attached. However, this does *not* mean that the kernel * didn't want to provide this information to us. Hence, let's * explicitly mark this information as available if it was * requested. */ @@ -1147,7 +1154,13 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call return 1; } -static int push_name_owner_changed(sd_bus *bus, const char *name, const char *old_owner, const char *new_owner) { +static int push_name_owner_changed( + sd_bus *bus, + const char *name, + const char *old_owner, + const char *new_owner, + const struct kdbus_timestamp *ts) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; int r; @@ -1167,6 +1180,7 @@ static int push_name_owner_changed(sd_bus *bus, const char *name, const char *ol return r; bus_message_set_sender_driver(bus, m); + message_set_timestamp(bus, m, ts); r = bus_seal_synthetic_message(bus, m); if (r < 0) @@ -1178,7 +1192,12 @@ static int push_name_owner_changed(sd_bus *bus, const char *name, const char *ol return 1; } -static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) { +static int translate_name_change( + sd_bus *bus, + const struct kdbus_msg *k, + const struct kdbus_item *d, + const struct kdbus_timestamp *ts) { + char new_owner[UNIQUE_NAME_MAX], old_owner[UNIQUE_NAME_MAX]; assert(bus); @@ -1199,10 +1218,15 @@ static int translate_name_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_ } else sprintf(new_owner, ":1.%llu", (unsigned long long) d->name_change.new_id.id); - return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner); + return push_name_owner_changed(bus, d->name_change.name, old_owner, new_owner, ts); } -static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) { +static int translate_id_change( + sd_bus *bus, + const struct kdbus_msg *k, + const struct kdbus_item *d, + const struct kdbus_timestamp *ts) { + char owner[UNIQUE_NAME_MAX]; assert(bus); @@ -1214,10 +1238,16 @@ static int translate_id_change(sd_bus *bus, struct kdbus_msg *k, struct kdbus_it return push_name_owner_changed( bus, owner, d->type == KDBUS_ITEM_ID_ADD ? NULL : owner, - d->type == KDBUS_ITEM_ID_ADD ? owner : NULL); + d->type == KDBUS_ITEM_ID_ADD ? owner : NULL, + ts); } -static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) { +static int translate_reply( + sd_bus *bus, + const struct kdbus_msg *k, + const struct kdbus_item *d, + const struct kdbus_timestamp *ts) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; int r; @@ -1235,7 +1265,7 @@ static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item * if (r < 0) return r; - bus_message_set_sender_driver(bus, m); + message_set_timestamp(bus, m, ts); r = bus_seal_synthetic_message(bus, m); if (r < 0) @@ -1248,9 +1278,7 @@ static int translate_reply(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item * } static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) { - struct kdbus_item *d, *found = NULL; - - static int (* const translate[])(sd_bus *bus, struct kdbus_msg *k, struct kdbus_item *d) = { + static int (* const translate[])(sd_bus *bus, const struct kdbus_msg *k, const struct kdbus_item *d, const struct kdbus_timestamp *ts) = { [KDBUS_ITEM_NAME_ADD - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change, [KDBUS_ITEM_NAME_REMOVE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change, [KDBUS_ITEM_NAME_CHANGE - _KDBUS_ITEM_KERNEL_BASE] = translate_name_change, @@ -1262,13 +1290,16 @@ static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) { [KDBUS_ITEM_REPLY_DEAD - _KDBUS_ITEM_KERNEL_BASE] = translate_reply, }; + struct kdbus_item *d, *found = NULL; + struct kdbus_timestamp *ts = NULL; + assert(bus); assert(k); assert(k->payload_type == KDBUS_PAYLOAD_KERNEL); KDBUS_ITEM_FOREACH(d, k, items) { if (d->type == KDBUS_ITEM_TIMESTAMP) - continue; + ts = &d->timestamp; if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) { if (found) @@ -1283,7 +1314,7 @@ static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) { return 0; } - return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found); + return translate[found->type - _KDBUS_ITEM_KERNEL_BASE](bus, k, found, ts); } int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {