summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/bus-kernel.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-11-24 21:41:40 +0100
committerLennart Poettering <lennart@poettering.net>2014-11-25 14:28:34 +0100
commit705a415f684f8e9ee19983e5859de00bbb1477cb (patch)
tree5cbabb53de92d7ee21ada427c24a88d18073c9dc /src/libsystemd/sd-bus/bus-kernel.c
parent1d58a1fe13cd725110be595c40cdc973d7e57d9e (diff)
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also: - adds support for euid, suid, fsuid, egid, sgid, fsgid fields. - makes augmentation of creds with data from /proc explicitly controllable to give apps better control over this, given that this is racy. - enables augmentation for kdbus connections (previously we only did it for dbus1). This is useful since with recent kdbus versions it is possible for clients to control the metadata they want to send. - changes sd_bus_query_sender_privilege() to take the euid of the client into consideration, if known - when we don't have permissions to read augmentation data from /proc, don't fail, just don't add the data in
Diffstat (limited to 'src/libsystemd/sd-bus/bus-kernel.c')
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c98
1 files changed, 80 insertions, 18 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index afac3b6bcc..79d29dc119 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -513,28 +513,75 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
break;
}
- case KDBUS_ITEM_CREDS:
- /* 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;
+ case KDBUS_ITEM_PIDS:
+
+ /* The PID starttime/TID might be missing,
+ * 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->pids.pid > 0) {
+ m->creds.pid = (pid_t) d->pids.pid;
+ m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
+ }
+
+ if (d->pids.starttime > 0) {
+ m->creds.pid_starttime = d->pids.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;
+ if (d->pids.tid > 0) {
+ m->creds.tid = (pid_t) d->pids.tid;
m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
}
+
+ break;
+
+ case KDBUS_ITEM_CREDS:
+
+ /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
+
+ if ((uid_t) d->creds.uid != (uid_t) -1) {
+ m->creds.uid = (uid_t) d->creds.uid;
+ m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.euid != (uid_t) -1) {
+ m->creds.euid = (uid_t) d->creds.euid;
+ m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.suid != (uid_t) -1) {
+ m->creds.suid = (uid_t) d->creds.suid;
+ m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.fsuid != (uid_t) -1) {
+ m->creds.fsuid = (uid_t) d->creds.fsuid;
+ m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.gid != (gid_t) -1) {
+ m->creds.gid = (gid_t) d->creds.gid;
+ m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.egid != (gid_t) -1) {
+ m->creds.egid = (gid_t) d->creds.egid;
+ m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.sgid != (gid_t) -1) {
+ m->creds.sgid = (gid_t) d->creds.sgid;
+ m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.fsgid != (gid_t) -1) {
+ m->creds.fsgid = (gid_t) d->creds.fsgid;
+ m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
+ }
+
break;
case KDBUS_ITEM_TIMESTAMP:
@@ -724,6 +771,9 @@ int bus_kernel_take_fd(sd_bus *b) {
if (b->fake_creds_valid)
sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
+ if (b->fake_pids_valid)
+ sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
+
if (b->fake_label) {
l = strlen(b->fake_label);
sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
@@ -751,6 +801,14 @@ int bus_kernel_take_fd(sd_bus *b) {
item = KDBUS_ITEM_NEXT(item);
}
+ if (b->fake_pids_valid) {
+ item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
+ item->type = KDBUS_ITEM_PIDS;
+ item->pids = b->fake_pids;
+
+ item = KDBUS_ITEM_NEXT(item);
+ }
+
if (b->fake_label) {
item->size = offsetof(struct kdbus_item, str) + l + 1;
item->type = KDBUS_ITEM_SECLABEL;
@@ -1237,9 +1295,13 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
assert(kdbus_mask);
- if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+ if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+ SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
m |= KDBUS_ATTACH_CREDS;
+ if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+ m |= KDBUS_ATTACH_PIDS;
+
if (mask & SD_BUS_CREDS_COMM)
m |= KDBUS_ATTACH_PID_COMM;