chiark / gitweb /
bus: set cookie_reply and update kdbus.h
[elogind.git] / src / libsystemd-bus / bus-kernel.c
index fb5266d44e5907da435286f37b69ff511b80a28c..c15218fe984097dcd3dbc7d29c90ffc4e31820eb 100644 (file)
@@ -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))
 
@@ -256,7 +257,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
                 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
         m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
         m->kdbus->cookie = m->header->serial;
-
+        m->kdbus->cookie_reply = m->reply_serial;
         m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
 
         d = m->kdbus->items;
@@ -319,7 +320,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 +333,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);
@@ -793,12 +794,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;
+                        /* UID/GID/PID are always valid */
                         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;
+                        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 = d->creds.tid;
+                                m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
+                        }
                         break;
 
                 case KDBUS_ITEM_TIMESTAMP:
@@ -830,6 +846,15 @@ 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: