X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-kernel.c;h=e8f4c581105f6a3b29166ec8876e48e2147abf98;hb=843f737ade9c73609a2280dd3dd16e18222a5dcb;hp=fb5266d44e5907da435286f37b69ff511b80a28c;hpb=8a0e0ed9ddfa208e414355881acb886270039268;p=elogind.git diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c index fb5266d44..e8f4c5811 100644 --- a/src/libsystemd-bus/bus-kernel.c +++ b/src/libsystemd-bus/bus-kernel.c @@ -35,6 +35,7 @@ #include "bus-kernel.h" #include "bus-bloom.h" #include "bus-util.h" +#include "cgroup-util.h" #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t)) @@ -174,10 +175,10 @@ static int bus_message_setup_bloom(sd_bus_message *m, void *bloom) { e = stpcpy(buf, "arg"); if (i < 10) - *(e++) = '0' + i; + *(e++) = '0' + (char) i; else { - *(e++) = '0' + (i / 10); - *(e++) = '0' + (i % 10); + *(e++) = '0' + (char) (i / 10); + *(e++) = '0' + (char) (i % 10); } *e = 0; @@ -257,7 +258,10 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) { m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS; m->kdbus->cookie = m->header->serial; - m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC; + if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) + m->kdbus->cookie_reply = m->reply_cookie; + else + m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC; d = m->kdbus->items; @@ -319,7 +323,7 @@ fail: int bus_kernel_take_fd(sd_bus *b) { struct kdbus_cmd_hello *hello; struct kdbus_item *item; - size_t l, sz; + size_t l = 0, sz; int r; assert(b); @@ -332,7 +336,7 @@ int bus_kernel_take_fd(sd_bus *b) { sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)); if (b->fake_creds_valid) - sz += ALIGN8(offsetof(struct kdbus_item, creds)); + sz += ALIGN8(offsetof(struct kdbus_item, creds)) + sizeof(struct kdbus_creds); if (b->fake_label) { l = strlen(b->fake_label); @@ -466,7 +470,7 @@ int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m) { r = bus_message_new_synthetic_error( bus, - BUS_MESSAGE_SERIAL(m), + BUS_MESSAGE_COOKIE(m), &error, &reply); @@ -793,12 +797,27 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { } case KDBUS_ITEM_CREDS: - m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC; - m->creds.uid = d->creds.uid; - m->creds.gid = d->creds.gid; - m->creds.pid = d->creds.pid; - m->creds.tid = d->creds.tid; - m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID) & bus->creds_mask; + /* UID/GID/PID are always valid */ + m->creds.uid = (uid_t) d->creds.uid; + m->creds.gid = (gid_t) d->creds.gid; + m->creds.pid = (pid_t) d->creds.pid; + m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask; + + /* The PID starttime/TID might be missing + * however, when the data is faked by some + * data bus proxy and it lacks that + * information about the real client since + * SO_PEERCRED is used for that */ + + if (d->creds.starttime > 0) { + m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC; + m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask; + } + + if (d->creds.tid > 0) { + m->creds.tid = (pid_t) d->creds.tid; + m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask; + } break; case KDBUS_ITEM_TIMESTAMP: @@ -830,11 +849,20 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { case KDBUS_ITEM_CGROUP: m->creds.cgroup = d->str; m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask; + + if (!bus->cgroup_root) { + r = cg_get_root_path(&bus->cgroup_root); + if (r < 0) + goto fail; + } + + m->creds.cgroup_root = bus->cgroup_root; + break; case KDBUS_ITEM_AUDIT: - m->creds.audit_session_id = d->audit.sessionid; - m->creds.audit_login_uid = d->audit.loginuid; + m->creds.audit_session_id = (uint32_t) d->audit.sessionid; + m->creds.audit_login_uid = (uid_t) d->audit.loginuid; m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask; break; @@ -845,10 +873,16 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { break; case KDBUS_ITEM_DST_NAME: + if (!service_name_is_valid(d->str)) + return -EBADMSG; + destination = d->str; break; case KDBUS_ITEM_NAME: + if (!service_name_is_valid(d->name.name)) + return -EBADMSG; + r = strv_extend(&m->creds.well_known_names, d->name.name); if (r < 0) goto fail; @@ -1103,7 +1137,7 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) { return 0; } -int bus_kernel_create_bus(const char *name, char **s) { +int bus_kernel_create_bus(const char *name, bool world, char **s) { struct kdbus_cmd_make *make; struct kdbus_item *n; int fd; @@ -1135,7 +1169,7 @@ int bus_kernel_create_bus(const char *name, char **s) { n->type = KDBUS_ITEM_MAKE_NAME; make->size += ALIGN8(n->size); - make->flags = KDBUS_MAKE_POLICY_OPEN; + make->flags = KDBUS_MAKE_POLICY_OPEN | (world ? KDBUS_MAKE_ACCESS_WORLD : 0); if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) { close_nointr_nofail(fd);