diff options
-rw-r--r-- | src/bus-proxyd/bus-proxyd.c | 10 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-control.c | 122 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-convenience.c | 25 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.c | 369 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.h | 7 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-dump.c | 21 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-internal.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 98 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/kdbus.h | 103 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 2 | ||||
-rw-r--r-- | src/systemd/sd-bus.h | 57 |
11 files changed, 596 insertions, 220 deletions
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c index 9c4f2a6ad9..32c8242221 100644 --- a/src/bus-proxyd/bus-proxyd.c +++ b/src/bus-proxyd/bus-proxyd.c @@ -1242,9 +1242,17 @@ int main(int argc, char *argv[]) { } if (ucred.pid > 0) { - a->fake_creds.pid = ucred.pid; + a->fake_pids.pid = ucred.pid; + a->fake_pids_valid = true; + a->fake_creds.uid = ucred.uid; + a->fake_creds.euid = (uid_t) -1; + a->fake_creds.suid = (uid_t) -1; + a->fake_creds.fsuid = (uid_t) -1; a->fake_creds.gid = ucred.gid; + a->fake_creds.egid = (gid_t) -1; + a->fake_creds.sgid = (gid_t) -1; + a->fake_creds.fsgid = (gid_t) -1; a->fake_creds_valid = true; } diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index c25a4911f5..7db912b64b 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -405,24 +405,65 @@ static int bus_populate_creds_from_items(sd_bus *bus, switch (item->type) { + case KDBUS_ITEM_PIDS: + + if (mask & SD_BUS_CREDS_PID && item->pids.pid > 0) { + c->pid = (pid_t) item->pids.pid; + c->mask |= SD_BUS_CREDS_PID; + } + + if (mask & SD_BUS_CREDS_TID && item->pids.tid > 0) { + c->tid = (pid_t) item->pids.tid; + c->mask |= SD_BUS_CREDS_TID; + } + + if (mask & SD_BUS_CREDS_PID_STARTTIME && item->pids.starttime > 0) { + c->pid_starttime = item->pids.starttime; + c->mask |= SD_BUS_CREDS_PID_STARTTIME; + } + + break; + case KDBUS_ITEM_CREDS: - m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask; - if (m) { + if (mask & SD_BUS_CREDS_UID && (uid_t) item->creds.uid != (uid_t) -1) { c->uid = (uid_t) item->creds.uid; - c->pid = (pid_t) item->creds.pid; + c->mask |= SD_BUS_CREDS_UID; + } + + if (mask & SD_BUS_CREDS_EUID && (uid_t) item->creds.euid != (uid_t) -1) { + c->euid = (uid_t) item->creds.euid; + c->mask |= SD_BUS_CREDS_EUID; + } + + if (mask & SD_BUS_CREDS_SUID && (uid_t) item->creds.suid != (uid_t) -1) { + c->suid = (uid_t) item->creds.suid; + c->mask |= SD_BUS_CREDS_SUID; + } + + if (mask & SD_BUS_CREDS_FSUID && (uid_t) item->creds.fsuid != (uid_t) -1) { + c->fsuid = (uid_t) item->creds.fsuid; + c->mask |= SD_BUS_CREDS_FSUID; + } + + if (mask & SD_BUS_CREDS_GID && (gid_t) item->creds.gid != (gid_t) -1) { c->gid = (gid_t) item->creds.gid; - c->mask |= m; + c->mask |= SD_BUS_CREDS_GID; } - if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) { - c->tid = (pid_t) item->creds.tid; - c->mask |= SD_BUS_CREDS_TID; + if (mask & SD_BUS_CREDS_EGID && (gid_t) item->creds.egid != (gid_t) -1) { + c->egid = (gid_t) item->creds.egid; + c->mask |= SD_BUS_CREDS_EGID; } - if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) { - c->pid_starttime = item->creds.starttime; - c->mask |= SD_BUS_CREDS_PID_STARTTIME; + if (mask & SD_BUS_CREDS_SGID && (gid_t) item->creds.sgid != (gid_t) -1) { + c->sgid = (gid_t) item->creds.sgid; + c->mask |= SD_BUS_CREDS_SGID; + } + + if (mask & SD_BUS_CREDS_FSGID && (gid_t) item->creds.fsgid != (gid_t) -1) { + c->fsgid = (gid_t) item->creds.fsgid; + c->mask |= SD_BUS_CREDS_FSGID; } break; @@ -581,6 +622,19 @@ static int bus_get_name_creds_kdbus( cmd->size = size; kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags); + /* If augmentation is on, and the bus doesn't didn't allow us + * to get the bits we want, then ask for the PID/TID so that we + * can read the rest from /proc. */ + if ((mask & SD_BUS_CREDS_AUGMENT) && + (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| + SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE| + 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| + SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS| + SD_BUS_CREDS_SELINUX_CONTEXT| + SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))) + cmd->flags |= KDBUS_ATTACH_PIDS; + r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd); if (r < 0) return -errno; @@ -615,6 +669,10 @@ static int bus_get_name_creds_kdbus( if (r < 0) goto fail; + r = bus_creds_add_more(c, mask, 0, 0); + if (r < 0) + goto fail; + if (creds) { *creds = c; c = NULL; @@ -673,11 +731,17 @@ static int bus_get_name_creds_dbus1( c->mask |= SD_BUS_CREDS_UNIQUE_NAME; } - if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID| - SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE| - 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| - SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS| - SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) { + if ((mask & SD_BUS_CREDS_PID) || + ((mask & SD_BUS_CREDS_AUGMENT) && + (mask & (SD_BUS_CREDS_PID_STARTTIME| + 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| + SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE| + 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| + SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS| + SD_BUS_CREDS_SELINUX_CONTEXT| + SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) { + uint32_t u; r = sd_bus_call_method( @@ -781,7 +845,7 @@ _public_ int sd_bus_get_name_creds( assert_return(bus, -EINVAL); assert_return(name, -EINVAL); - assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP); + assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP); assert_return(mask == 0 || creds, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); assert_return(service_name_is_valid(name), -EINVAL); @@ -802,7 +866,7 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r int r; assert_return(bus, -EINVAL); - assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP); + assert_return((mask & ~SD_BUS_CREDS_AUGMENT) <= _SD_BUS_CREDS_ALL, -ENOTSUP); assert_return(ret, -EINVAL); assert_return(!bus_pid_changed(bus), -ECHILD); @@ -837,7 +901,21 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r struct kdbus_info *creator_info; cmd.size = sizeof(cmd); - cmd.flags = _KDBUS_ATTACH_ALL; + kdbus_translate_attach_flags(mask, (uint64_t*) &cmd.flags); + + /* If augmentation is on, and the bus doesn't didn't allow us + * to get the bits we want, then ask for the PID/TID so that we + * can read the rest from /proc. */ + if ((mask & SD_BUS_CREDS_AUGMENT) && + (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| + SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE| + 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| + SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS| + SD_BUS_CREDS_SELINUX_CONTEXT| + SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID))) + cmd.flags |= KDBUS_ATTACH_PIDS; + r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd); if (r < 0) return -errno; @@ -849,12 +927,12 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r if (r < 0) return r; - } else { - r = bus_creds_add_more(c, mask, pid, 0); - if (r < 0) - return r; } + r = bus_creds_add_more(c, mask, pid, 0); + if (r < 0) + return r; + *ret = c; c = NULL; return 0; diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 8081a2f9c0..ae0f4fa217 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -476,6 +476,7 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) { _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; uid_t our_uid; + bool know_caps = false; int r; assert_return(call, -EINVAL); @@ -486,21 +487,21 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) if (!BUS_IS_OPEN(call->bus->state)) return -ENOTCONN; - /* We only trust the effective capability set if this is - * kdbus. On classic dbus1 we cannot retrieve the value - * without races. Since this function is supposed to be useful - * for authentication decision we hence avoid requesting and - * using that information. */ - if (call->bus->is_kernel && capability >= 0) { - r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds); + if (capability >= 0) { + r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds); if (r < 0) return r; + /* Note that not even on kdbus we might have the caps + * field, due to faked identities, or namespace + * translation issues. */ r = sd_bus_creds_has_effective_cap(creds, capability); if (r > 0) return 1; + if (r == 0) + know_caps = true; } else { - r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds); + r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID, &creds); if (r < 0) return r; } @@ -508,10 +509,14 @@ _public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) /* Now, check the UID, but only if the capability check wasn't * sufficient */ our_uid = getuid(); - if (our_uid != 0 || !call->bus->is_kernel || capability < 0) { + if (our_uid != 0 || !know_caps || capability < 0) { uid_t sender_uid; - r = sd_bus_creds_get_uid(creds, &sender_uid); + /* Try to use the EUID, if we have it. */ + r = sd_bus_creds_get_euid(creds, &sender_uid); + if (r < 0) + r = sd_bus_creds_get_uid(creds, &sender_uid); + if (r >= 0) { /* Sender has same UID as us, then let's grant access */ if (sender_uid == our_uid) diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index d27ef1edbf..02a73725c6 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -141,7 +141,7 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m if (!c) return -ENOMEM; - r = bus_creds_add_more(c, mask, pid, 0); + r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0); if (r < 0) { sd_bus_creds_unref(c); return r; @@ -169,6 +169,40 @@ _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) { return 0; } +_public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) { + assert_return(c, -EINVAL); + assert_return(euid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_EUID)) + return -ENODATA; + + *euid = c->euid; + return 0; +} + +_public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) { + assert_return(c, -EINVAL); + assert_return(suid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_SUID)) + return -ENODATA; + + *suid = c->suid; + return 0; +} + + +_public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) { + assert_return(c, -EINVAL); + assert_return(fsuid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_FSUID)) + return -ENODATA; + + *fsuid = c->fsuid; + return 0; +} + _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { assert_return(c, -EINVAL); assert_return(gid, -EINVAL); @@ -180,6 +214,41 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { return 0; } + +_public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) { + assert_return(c, -EINVAL); + assert_return(egid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_EGID)) + return -ENODATA; + + *egid = c->egid; + return 0; +} + +_public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) { + assert_return(c, -EINVAL); + assert_return(sgid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_SGID)) + return -ENODATA; + + *sgid = c->sgid; + return 0; +} + + +_public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) { + assert_return(c, -EINVAL); + assert_return(fsgid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_FSGID)) + return -ENODATA; + + *fsgid = c->fsgid; + return 0; +} + _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { assert_return(c, -EINVAL); assert_return(pid, -EINVAL); @@ -581,6 +650,9 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { assert(c); assert(c->allocated); + if (!(mask & SD_BUS_CREDS_AUGMENT)) + return 0; + missing = mask & ~c->mask; if (missing == 0) return 0; @@ -596,98 +668,120 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (pid <= 0) return 0; - if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | + if (pid > 0) { + c->pid = pid; + c->mask |= SD_BUS_CREDS_PID; + } + + if (tid > 0) { + c->tid = tid; + c->mask |= SD_BUS_CREDS_TID; + } + + if (missing & (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 | SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) { _cleanup_fclose_ FILE *f = NULL; - char line[LINE_MAX]; const char *p; p = procfs_file_alloca(pid, "status"); f = fopen(p, "re"); - if (!f) - return errno == ENOENT ? -ESRCH : -errno; - - FOREACH_LINE(line, f, return -errno) { - truncate_nl(line); - - if (missing & SD_BUS_CREDS_UID) { - p = startswith(line, "Uid:"); - if (p) { - unsigned long uid; - - p += strspn(p, WHITESPACE); - if (sscanf(p, "%lu", &uid) != 1) - return -EIO; - - c->uid = (uid_t) uid; - c->mask |= SD_BUS_CREDS_UID; - continue; + if (!f) { + if (errno == ENOENT) + return -ESRCH; + else if (errno != EPERM && errno != EACCES) + return -errno; + } else { + char line[LINE_MAX]; + + FOREACH_LINE(line, f, return -errno) { + truncate_nl(line); + + if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) { + p = startswith(line, "Uid:"); + if (p) { + unsigned long uid, euid, suid, fsuid; + + p += strspn(p, WHITESPACE); + if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4) + return -EIO; + + c->uid = (uid_t) uid; + c->euid = (uid_t) euid; + c->suid = (uid_t) suid; + c->fsuid = (uid_t) fsuid; + c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID); + continue; + } } - } - - if (missing & SD_BUS_CREDS_GID) { - p = startswith(line, "Gid:"); - if (p) { - unsigned long gid; - - p += strspn(p, WHITESPACE); - if (sscanf(p, "%lu", &gid) != 1) - return -EIO; - c->gid = (uid_t) gid; - c->mask |= SD_BUS_CREDS_GID; - continue; + if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) { + p = startswith(line, "Gid:"); + if (p) { + unsigned long gid, egid, sgid, fsgid; + + p += strspn(p, WHITESPACE); + if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4) + return -EIO; + + c->gid = (gid_t) gid; + c->egid = (gid_t) egid; + c->sgid = (gid_t) sgid; + c->fsgid = (gid_t) fsgid; + c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID); + continue; + } } - } - if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) { - p = startswith(line, "CapEff:"); - if (p) { - r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p); - if (r < 0) - return r; + if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) { + p = startswith(line, "CapEff:"); + if (p) { + r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p); + if (r < 0) + return r; - c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS; - continue; + c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS; + continue; + } } - } - if (missing & SD_BUS_CREDS_PERMITTED_CAPS) { - p = startswith(line, "CapPrm:"); - if (p) { - r = parse_caps(c, CAP_OFFSET_PERMITTED, p); - if (r < 0) - return r; + if (missing & SD_BUS_CREDS_PERMITTED_CAPS) { + p = startswith(line, "CapPrm:"); + if (p) { + r = parse_caps(c, CAP_OFFSET_PERMITTED, p); + if (r < 0) + return r; - c->mask |= SD_BUS_CREDS_PERMITTED_CAPS; - continue; + c->mask |= SD_BUS_CREDS_PERMITTED_CAPS; + continue; + } } - } - if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) { - p = startswith(line, "CapInh:"); - if (p) { - r = parse_caps(c, CAP_OFFSET_INHERITABLE, p); - if (r < 0) - return r; + if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) { + p = startswith(line, "CapInh:"); + if (p) { + r = parse_caps(c, CAP_OFFSET_INHERITABLE, p); + if (r < 0) + return r; - c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS; - continue; + c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS; + continue; + } } - } - if (missing & SD_BUS_CREDS_BOUNDING_CAPS) { - p = startswith(line, "CapBnd:"); - if (p) { - r = parse_caps(c, CAP_OFFSET_BOUNDING, p); - if (r < 0) - return r; + if (missing & SD_BUS_CREDS_BOUNDING_CAPS) { + p = startswith(line, "CapBnd:"); + if (p) { + r = parse_caps(c, CAP_OFFSET_BOUNDING, p); + if (r < 0) + return r; - c->mask |= SD_BUS_CREDS_BOUNDING_CAPS; - continue; + c->mask |= SD_BUS_CREDS_BOUNDING_CAPS; + continue; + } } } } @@ -697,11 +791,13 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { unsigned long long st; r = get_starttime_of_pid(pid, &st); - if (r < 0) - return r; - - c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK); - c->mask |= SD_BUS_CREDS_PID_STARTTIME; + if (r < 0) { + if (r != -EPERM && r != -EACCES) + return r; + } else { + c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK); + c->mask |= SD_BUS_CREDS_PID_STARTTIME; + } } if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) { @@ -709,26 +805,29 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { p = procfs_file_alloca(pid, "attr/current"); r = read_one_line_file(p, &c->label); - if (r < 0 && r != -ENOENT && r != -EINVAL) - return r; - else if (r >= 0) + if (r < 0) { + if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES) + return r; + } else c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT; } if (missing & SD_BUS_CREDS_COMM) { r = get_process_comm(pid, &c->comm); - if (r < 0) - return r; - - c->mask |= SD_BUS_CREDS_COMM; + if (r < 0) { + if (r != -EPERM && r != -EACCES) + return r; + } else + c->mask |= SD_BUS_CREDS_COMM; } if (missing & SD_BUS_CREDS_EXE) { r = get_process_exe(pid, &c->exe); - if (r < 0) - return r; - - c->mask |= SD_BUS_CREDS_EXE; + if (r < 0) { + if (r != -EPERM && r != -EACCES) + return r; + } else + c->mask |= SD_BUS_CREDS_EXE; } if (missing & SD_BUS_CREDS_CMDLINE) { @@ -736,14 +835,18 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { p = procfs_file_alloca(pid, "cmdline"); r = read_full_file(p, &c->cmdline, &c->cmdline_size); - if (r < 0) - return r; - - if (c->cmdline_size == 0) { - free(c->cmdline); - c->cmdline = NULL; - } else - c->mask |= SD_BUS_CREDS_CMDLINE; + if (r < 0) { + if (r == -ENOENT) + return -ESRCH; + if (r != -EPERM && r != -EACCES) + return r; + } else { + if (c->cmdline_size == 0) { + free(c->cmdline); + c->cmdline = NULL; + } else + c->mask |= SD_BUS_CREDS_CMDLINE; + } } if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) { @@ -753,38 +856,45 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { return -ENOMEM; r = read_one_line_file(p, &c->tid_comm); - if (r < 0) - return r == -ENOENT ? -ESRCH : r; - - c->mask |= SD_BUS_CREDS_TID_COMM; + if (r < 0) { + if (r == -ENOENT) + return -ESRCH; + if (r != -EPERM && r != -EACCES) + return r; + } else + c->mask |= SD_BUS_CREDS_TID_COMM; } if (missing & (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)) { r = cg_pid_get_path(NULL, pid, &c->cgroup); - if (r < 0) - return r; - - r = cg_get_root_path(&c->cgroup_root); - if (r < 0) - return r; - - c->mask |= missing & (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); + if (r < 0) { + if (r != -EPERM && r != -EACCES) + return r; + } else { + r = cg_get_root_path(&c->cgroup_root); + if (r < 0) + return r; + + c->mask |= missing & (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); + } } if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) { r = audit_session_from_pid(pid, &c->audit_session_id); - if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT) - return r; - else if (r >= 0) + if (r < 0) { + if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + return r; + } else c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID; } if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) { r = audit_loginuid_from_pid(pid, &c->audit_login_uid); - if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT) - return r; - else if (r >= 0) + if (r < 0) { + if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + return r; + } else c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; } @@ -798,8 +908,9 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) assert(c); assert(ret); - if ((mask & ~c->mask) == 0) { - /* There's already all data we need. */ + if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) { + /* There's already all data we need, or augmentation + * wasn't turned on. */ *ret = sd_bus_creds_ref(c); return 0; @@ -816,11 +927,41 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) n->mask |= SD_BUS_CREDS_UID; } + if (c->mask & mask & SD_BUS_CREDS_EUID) { + n->euid = c->euid; + n->mask |= SD_BUS_CREDS_EUID; + } + + if (c->mask & mask & SD_BUS_CREDS_SUID) { + n->suid = c->suid; + n->mask |= SD_BUS_CREDS_SUID; + } + + if (c->mask & mask & SD_BUS_CREDS_FSUID) { + n->fsuid = c->fsuid; + n->mask |= SD_BUS_CREDS_FSUID; + } + if (c->mask & mask & SD_BUS_CREDS_GID) { n->gid = c->gid; n->mask |= SD_BUS_CREDS_GID; } + if (c->mask & mask & SD_BUS_CREDS_EGID) { + n->egid = c->egid; + n->mask |= SD_BUS_CREDS_EGID; + } + + if (c->mask & mask & SD_BUS_CREDS_SGID) { + n->sgid = c->sgid; + n->mask |= SD_BUS_CREDS_SGID; + } + + if (c->mask & mask & SD_BUS_CREDS_FSGID) { + n->fsgid = c->fsgid; + n->mask |= SD_BUS_CREDS_FSGID; + } + if (c->mask & mask & SD_BUS_CREDS_PID) { n->pid = c->pid; n->mask |= SD_BUS_CREDS_PID; diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h index cf1f611237..15821a57d2 100644 --- a/src/libsystemd/sd-bus/bus-creds.h +++ b/src/libsystemd/sd-bus/bus-creds.h @@ -32,7 +32,14 @@ struct sd_bus_creds { uint64_t mask; uid_t uid; + uid_t euid; + uid_t suid; + uid_t fsuid; gid_t gid; + gid_t egid; + gid_t sgid; + gid_t fsgid; + pid_t pid; usec_t pid_starttime; pid_t tid; diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index 5e96b00263..d6e5546053 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -360,15 +360,32 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) { fprintf(f, "%sPIDStartTime=%s"USEC_FMT"%s", prefix, color, c->pid_starttime, suffix); if (c->mask & SD_BUS_CREDS_TID) fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix); + + if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID)))) + fputs("\n", f); + if (c->mask & SD_BUS_CREDS_UID) fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix); + if (c->mask & SD_BUS_CREDS_EUID) + fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix); + if (c->mask & SD_BUS_CREDS_SUID) + fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix); + if (c->mask & SD_BUS_CREDS_FSUID) + fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix); r = sd_bus_creds_get_owner_uid(c, &owner); if (r >= 0) fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix); if (c->mask & SD_BUS_CREDS_GID) fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix); - - if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0)) + if (c->mask & SD_BUS_CREDS_EGID) + fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix); + if (c->mask & SD_BUS_CREDS_SGID) + fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix); + if (c->mask & SD_BUS_CREDS_FSGID) + fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix); + + if (terse && ((c->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)) || r >= 0)) fputs("\n", f); if (c->mask & SD_BUS_CREDS_COMM) diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index f6b0211c2c..977b3407ba 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -206,6 +206,7 @@ struct sd_bus { bool nodes_modified:1; bool trusted:1; bool fake_creds_valid:1; + bool fake_pids_valid:1; bool manual_peer_interface:1; bool is_system:1; bool is_user:1; @@ -306,6 +307,7 @@ struct sd_bus { pid_t tid; struct kdbus_creds fake_creds; + struct kdbus_pids fake_pids; char *fake_label; char *cgroup_root; 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; diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h index e3a80c352d..65266ee212 100644 --- a/src/libsystemd/sd-bus/kdbus.h +++ b/src/libsystemd/sd-bus/kdbus.h @@ -58,22 +58,43 @@ struct kdbus_notify_name_change { /** * struct kdbus_creds - process credentials * @uid: User ID + * @euid: Effective UID + * @suid: Saved UID + * @fsuid: Filesystem UID * @gid: Group ID - * @pid: Process ID - * @tid: Thread ID - * @starttime: Starttime of the process - * - * The starttime of the process PID. This is useful to detect PID overruns - * from the client side. i.e. if you use the PID to look something up in - * /proc/$PID/ you can afterwards check the starttime field of it, to ensure - * you didn't run into a PID overrun. + * @egid: Effective GID + * @sgid: Saved GID + * @fsgid: Filesystem GID * * Attached to: * KDBUS_ITEM_CREDS */ struct kdbus_creds { __u64 uid; + __u64 euid; + __u64 suid; + __u64 fsuid; __u64 gid; + __u64 egid; + __u64 sgid; + __u64 fsgid; +}; + +/** + * struct kdbus_pids - process identifiers + * @pid: Process ID + * @tid: Thread ID + * @starttime: Starttime of the process + * + * The PID, TID and starttime of a process. The start tmie is useful to detect + * PID overruns from the client side. i.e. if you use the PID to look something + * up in /proc/$PID/ you can afterwards check the starttime field of it, to + * ensure you didn't run into a PID overrun. + * + * Attached to: + * KDBUS_ITEM_PIDS + */ +struct kdbus_pids { __u64 pid; __u64 tid; __u64 starttime; @@ -229,14 +250,19 @@ struct kdbus_policy_access { * @KDBUS_ITEM_NAME: Well-know name with flags * @_KDBUS_ITEM_ATTACH_BASE: Start of metadata attach items * @KDBUS_ITEM_TIMESTAMP: Timestamp - * @KDBUS_ITEM_CREDS: Process credential + * @KDBUS_ITEM_CREDS: Process credentials + * @KDBUS_ITEM_PIDS: Process identifiers * @KDBUS_ITEM_AUXGROUPS: Auxiliary process groups * @KDBUS_ITEM_OWNED_NAME: A name owned by the associated * connection * @KDBUS_ITEM_TID_COMM: Thread ID "comm" identifier + * (Don't trust this, see below.) * @KDBUS_ITEM_PID_COMM: Process ID "comm" identifier + * (Don't trust this, see below.) * @KDBUS_ITEM_EXE: The path of the executable + * (Don't trust this, see below.) * @KDBUS_ITEM_CMDLINE: The process command line + * (Don't trust this, see below.) * @KDBUS_ITEM_CGROUP: The croup membership * @KDBUS_ITEM_CAPS: The process capabilities * @KDBUS_ITEM_SECLABEL: The security label @@ -253,6 +279,12 @@ struct kdbus_policy_access { * @KDBUS_ITEM_ID_REMOVE: Notification in kdbus_notify_id_change * @KDBUS_ITEM_REPLY_TIMEOUT: Timeout has been reached * @KDBUS_ITEM_REPLY_DEAD: Destination died + * + * N.B: The process and thread COMM fields, as well as the CMDLINE and + * EXE fields may be altered by unprivileged processes und should + * hence *not* used for security decisions. Peers should make use of + * these items only for informational purposes, such as generating log + * records. */ enum kdbus_item_type { _KDBUS_ITEM_NULL, @@ -275,6 +307,7 @@ enum kdbus_item_type { _KDBUS_ITEM_ATTACH_BASE = 0x1000, KDBUS_ITEM_TIMESTAMP = _KDBUS_ITEM_ATTACH_BASE, KDBUS_ITEM_CREDS, + KDBUS_ITEM_PIDS, KDBUS_ITEM_AUXGROUPS, KDBUS_ITEM_OWNED_NAME, KDBUS_ITEM_TID_COMM, @@ -336,6 +369,7 @@ struct kdbus_item { __u64 id; struct kdbus_vec vec; struct kdbus_creds creds; + struct kdbus_pids pids; struct kdbus_audit audit; struct kdbus_caps caps; struct kdbus_timestamp timestamp; @@ -455,6 +489,10 @@ enum kdbus_recv_flags { * @offset: Returned offset in the pool where the message is * stored. The user must use KDBUS_CMD_FREE to free * the allocated memory. + * @dropped_msgs: In case the KDBUS_CMD_MSG_RECV ioctl returns + * -EOVERFLOW, this field will contain the number of + * broadcast messages that have been lost since the + * last call. * * This struct is used with the KDBUS_CMD_MSG_RECV ioctl. */ @@ -462,7 +500,10 @@ struct kdbus_cmd_recv { __u64 flags; __u64 kernel_flags; __s64 priority; - __u64 offset; + union { + __u64 offset; + __u64 dropped_msgs; + }; } __attribute__((aligned(8))); /** @@ -547,6 +588,7 @@ enum kdbus_hello_flags { * enum kdbus_attach_flags - flags for metadata attachments * @KDBUS_ATTACH_TIMESTAMP: Timestamp * @KDBUS_ATTACH_CREDS: Credentials + * @KDBUS_ATTACH_PIDS: PIDs * @KDBUS_ATTACH_AUXGROUPS: Auxiliary groups * @KDBUS_ATTACH_NAMES: Well-known names * @KDBUS_ATTACH_TID_COMM: The "comm" process identifier of the TID @@ -565,18 +607,19 @@ enum kdbus_hello_flags { enum kdbus_attach_flags { KDBUS_ATTACH_TIMESTAMP = 1ULL << 0, KDBUS_ATTACH_CREDS = 1ULL << 1, - KDBUS_ATTACH_AUXGROUPS = 1ULL << 2, - KDBUS_ATTACH_NAMES = 1ULL << 3, - KDBUS_ATTACH_TID_COMM = 1ULL << 4, - KDBUS_ATTACH_PID_COMM = 1ULL << 5, - KDBUS_ATTACH_EXE = 1ULL << 6, - KDBUS_ATTACH_CMDLINE = 1ULL << 7, - KDBUS_ATTACH_CGROUP = 1ULL << 8, - KDBUS_ATTACH_CAPS = 1ULL << 9, - KDBUS_ATTACH_SECLABEL = 1ULL << 10, - KDBUS_ATTACH_AUDIT = 1ULL << 11, - KDBUS_ATTACH_CONN_DESCRIPTION = 1ULL << 12, - _KDBUS_ATTACH_ALL = (1ULL << 13) - 1, + KDBUS_ATTACH_PIDS = 1ULL << 2, + KDBUS_ATTACH_AUXGROUPS = 1ULL << 3, + KDBUS_ATTACH_NAMES = 1ULL << 4, + KDBUS_ATTACH_TID_COMM = 1ULL << 5, + KDBUS_ATTACH_PID_COMM = 1ULL << 6, + KDBUS_ATTACH_EXE = 1ULL << 7, + KDBUS_ATTACH_CMDLINE = 1ULL << 8, + KDBUS_ATTACH_CGROUP = 1ULL << 9, + KDBUS_ATTACH_CAPS = 1ULL << 10, + KDBUS_ATTACH_SECLABEL = 1ULL << 11, + KDBUS_ATTACH_AUDIT = 1ULL << 12, + KDBUS_ATTACH_CONN_DESCRIPTION = 1ULL << 13, + _KDBUS_ATTACH_ALL = (1ULL << 14) - 1, _KDBUS_ATTACH_ANY = ~0ULL }; @@ -619,8 +662,8 @@ struct kdbus_cmd_hello { /** * enum kdbus_make_flags - Flags for KDBUS_CMD_{BUS,EP,NS}_MAKE - * @KDBUS_MAKE_ACCESS_GROUP: Make the device node group-accessible - * @KDBUS_MAKE_ACCESS_WORLD: Make the device node world-accessible + * @KDBUS_MAKE_ACCESS_GROUP: Make the bus or endpoint node group-accessible + * @KDBUS_MAKE_ACCESS_WORLD: Make the bus or endpoint node world-accessible */ enum kdbus_make_flags { KDBUS_MAKE_ACCESS_GROUP = 1ULL << 0, @@ -713,7 +756,7 @@ enum kdbus_name_list_flags { /** * struct kdbus_cmd_name_list - request a list of name entries * @flags: Flags for the query (KDBUS_NAME_LIST_*), - * userspace → kernel + * userspace → kernel * @kernel_flags: Supported flags for queries, kernel → userspace * @offset: The returned offset in the caller's pool buffer. * The user must use KDBUS_CMD_FREE to free the @@ -834,16 +877,16 @@ struct kdbus_cmd_match { /** * Ioctl API - * KDBUS_CMD_BUS_MAKE: After opening the "control" device node, this - * command creates a new bus with the specified + * KDBUS_CMD_BUS_MAKE: After opening the "control" node, this command + * creates a new bus with the specified * name. The bus is immediately shut down and - * cleaned up when the opened "control" device node - * is closed. + * cleaned up when the opened file descriptor is + * closed. * KDBUS_CMD_ENDPOINT_MAKE: Creates a new named special endpoint to talk to * the bus. Such endpoints usually carry a more * restrictive policy and grant restricted access * to specific applications. - * KDBUS_CMD_HELLO: By opening the bus device node a connection is + * KDBUS_CMD_HELLO: By opening the bus node, a connection is * created. After a HELLO the opened connection * becomes an active peer on the bus. * KDBUS_CMD_BYEBYE: Disconnect a connection. If there are no diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index b1a1f79d86..5aa8eacebb 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1070,7 +1070,7 @@ _public_ int sd_bus_open(sd_bus **ret) { /* We don't know whether the bus is trusted or not, so better * be safe, and authenticate everything */ b->trusted = false; - b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS; + b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS; r = sd_bus_start(b); if (r < 0) diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 58a898080b..21d693b4bc 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -53,28 +53,35 @@ enum { SD_BUS_CREDS_PID_STARTTIME = 1ULL << 1, SD_BUS_CREDS_TID = 1ULL << 2, SD_BUS_CREDS_UID = 1ULL << 3, - SD_BUS_CREDS_GID = 1ULL << 4, - SD_BUS_CREDS_COMM = 1ULL << 5, - SD_BUS_CREDS_TID_COMM = 1ULL << 6, - SD_BUS_CREDS_EXE = 1ULL << 7, - SD_BUS_CREDS_CMDLINE = 1ULL << 8, - SD_BUS_CREDS_CGROUP = 1ULL << 9, - SD_BUS_CREDS_UNIT = 1ULL << 10, - SD_BUS_CREDS_USER_UNIT = 1ULL << 11, - SD_BUS_CREDS_SLICE = 1ULL << 12, - SD_BUS_CREDS_SESSION = 1ULL << 13, - SD_BUS_CREDS_OWNER_UID = 1ULL << 14, - SD_BUS_CREDS_EFFECTIVE_CAPS = 1ULL << 15, - SD_BUS_CREDS_PERMITTED_CAPS = 1ULL << 16, - SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 17, - SD_BUS_CREDS_BOUNDING_CAPS = 1ULL << 18, - SD_BUS_CREDS_SELINUX_CONTEXT = 1ULL << 19, - SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 20, - SD_BUS_CREDS_AUDIT_LOGIN_UID = 1ULL << 21, - SD_BUS_CREDS_UNIQUE_NAME = 1ULL << 22, - SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 23, - SD_BUS_CREDS_DESCRIPTION = 1ULL << 24, - _SD_BUS_CREDS_ALL = (1ULL << 25) -1, + SD_BUS_CREDS_EUID = 1ULL << 4, + SD_BUS_CREDS_SUID = 1ULL << 5, + SD_BUS_CREDS_FSUID = 1ULL << 6, + SD_BUS_CREDS_GID = 1ULL << 7, + SD_BUS_CREDS_EGID = 1ULL << 8, + SD_BUS_CREDS_SGID = 1ULL << 9, + SD_BUS_CREDS_FSGID = 1ULL << 10, + SD_BUS_CREDS_COMM = 1ULL << 11, + SD_BUS_CREDS_TID_COMM = 1ULL << 12, + SD_BUS_CREDS_EXE = 1ULL << 13, + SD_BUS_CREDS_CMDLINE = 1ULL << 14, + SD_BUS_CREDS_CGROUP = 1ULL << 15, + SD_BUS_CREDS_UNIT = 1ULL << 16, + SD_BUS_CREDS_USER_UNIT = 1ULL << 17, + SD_BUS_CREDS_SLICE = 1ULL << 18, + SD_BUS_CREDS_SESSION = 1ULL << 19, + SD_BUS_CREDS_OWNER_UID = 1ULL << 20, + SD_BUS_CREDS_EFFECTIVE_CAPS = 1ULL << 21, + SD_BUS_CREDS_PERMITTED_CAPS = 1ULL << 22, + SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 23, + SD_BUS_CREDS_BOUNDING_CAPS = 1ULL << 24, + SD_BUS_CREDS_SELINUX_CONTEXT = 1ULL << 25, + SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 26, + SD_BUS_CREDS_AUDIT_LOGIN_UID = 1ULL << 27, + SD_BUS_CREDS_UNIQUE_NAME = 1ULL << 28, + SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 29, + SD_BUS_CREDS_DESCRIPTION = 1ULL << 30, + SD_BUS_CREDS_AUGMENT = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */ + _SD_BUS_CREDS_ALL = (1ULL << 31) -1, }; enum { @@ -305,7 +312,13 @@ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid); int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec); int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid); int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid); +int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid); +int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid); +int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid); int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid); +int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid); +int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid); +int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid); int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm); int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm); int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe); |