chiark / gitweb /
bus: only accept kdbus creds if they are valid
authorLennart Poettering <lennart@poettering.net>
Tue, 24 Dec 2013 15:20:47 +0000 (16:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 24 Dec 2013 15:20:47 +0000 (16:20 +0100)
This allows userspace to fake kdbus creds via struct ucred in the proxy,
without making the recieving side choke on the missing fields of the
kdbus struct, more precisel pid_starttime and tid

src/libsystemd-bus/bus-control.c
src/libsystemd-bus/bus-kernel.c

index 1eed7b9e320952036e3f78899cd65d635381717d..55986f349b4da51e47af82ec262400febb68ab58 100644 (file)
@@ -407,17 +407,25 @@ static int bus_get_owner_kdbus(
                 switch (item->type) {
 
                 case KDBUS_ITEM_CREDS:
-                        m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
-                             SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
+                        m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
 
                         if (m) {
                                 c->uid = item->creds.uid;
                                 c->pid = item->creds.pid;
                                 c->gid = item->creds.gid;
+                                c->mask |= m;
+                        }
+
+                        if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
                                 c->tid = item->creds.tid;
+                                c->mask |= SD_BUS_CREDS_TID;
+                        }
+
+                        if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
                                 c->pid_starttime = item->creds.starttime;
-                                c->mask |= m;
+                                c->mask |= SD_BUS_CREDS_PID_STARTTIME;
                         }
+
                         break;
 
                 case KDBUS_ITEM_PID_COMM:
index 05544e1e477403716292383feef0cdcaaa2ab2e1..19d97b7e0016b5ef86608e146caef980e133deac 100644 (file)
@@ -793,12 +793,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: