X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-control.c;h=442def7f780ab8f6e792e09d59ab4c885d13c894;hp=813c97f6501f6a022152f294b06739c718da131b;hb=eea0b59193f37fcc9ee227de26d0009e6bdc6d92;hpb=32802361561403cb6441198c82d9c499e0513863 diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 813c97f65..442def7f7 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -33,6 +33,7 @@ #include "bus-control.h" #include "bus-bloom.h" #include "bus-util.h" +#include "capability.h" #include "cgroup-util.h" _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) { @@ -136,6 +137,10 @@ _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) assert_return(service_name_is_valid(name), -EINVAL); assert_return(name[0] != ':', -EINVAL); + /* Don't allow requesting the special driver and local names */ + if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local")) + return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; @@ -214,6 +219,10 @@ _public_ int sd_bus_release_name(sd_bus *bus, const char *name) { assert_return(service_name_is_valid(name), -EINVAL); assert_return(name[0] != ':', -EINVAL); + /* Don't allow releasing the special driver and local names */ + if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local")) + return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; @@ -232,6 +241,7 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) { /* Caller will free half-constructed list on failure... */ + cmd.size = sizeof(cmd); cmd.flags = flags; r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd); @@ -519,8 +529,11 @@ static int bus_populate_creds_from_items( SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask; if (m) { - c->capability_size = item->size - offsetof(struct kdbus_item, caps.caps); - c->capability = memdup(item->caps.caps, c->capability_size); + if (item->caps.last_cap != cap_last_cap() || + item->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(item->caps.last_cap, 32U) * 4 * 4) + return -EBADMSG; + + c->capability = memdup(item->caps.caps, item->size - offsetof(struct kdbus_item, caps.caps)); if (!c->capability) return -ENOMEM; @@ -609,6 +622,9 @@ int bus_get_name_creds_kdbus( uint64_t id; int r; + if (streq(name, "org.freedesktop.DBus")) + return -ENOTSUP; + r = bus_kernel_parse_unique_name(name, &id); if (r < 0) return r; @@ -628,8 +644,8 @@ int bus_get_name_creds_kdbus( cmd->size = size; cmd->flags = attach_flags_to_kdbus(mask); - /* 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 + /* If augmentation is on, and the bus didn't provide us + * 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| @@ -746,7 +762,7 @@ static int bus_get_name_creds_dbus1( if ((mask & SD_BUS_CREDS_PID) || ((mask & SD_BUS_CREDS_AUGMENT) && - (mask & (SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID| + (mask & (SD_BUS_CREDS_UID|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| @@ -782,7 +798,7 @@ static int bus_get_name_creds_dbus1( reply = sd_bus_message_unref(reply); } - if (mask & SD_BUS_CREDS_UID) { + if (mask & SD_BUS_CREDS_EUID) { uint32_t u; r = sd_bus_call_method( @@ -802,8 +818,8 @@ static int bus_get_name_creds_dbus1( if (r < 0) return r; - c->uid = u; - c->mask |= SD_BUS_CREDS_UID; + c->euid = u; + c->mask |= SD_BUS_CREDS_EUID; reply = sd_bus_message_unref(reply); } @@ -866,6 +882,9 @@ _public_ int sd_bus_get_name_creds( assert_return(service_name_is_valid(name), -EINVAL); assert_return(bus->bus_client, -ENODATA); + if (streq(name, "org.freedesktop.DBus.Local")) + return -EINVAL; + if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; @@ -942,13 +961,13 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds ** } if (bus->ucred.uid != UID_INVALID) { - c->uid = bus->ucred.uid; - c->mask |= SD_BUS_CREDS_UID & mask; + c->euid = bus->ucred.uid; + c->mask |= SD_BUS_CREDS_EUID & mask; } if (bus->ucred.gid != GID_INVALID) { - c->gid = bus->ucred.gid; - c->mask |= SD_BUS_CREDS_GID & mask; + c->egid = bus->ucred.gid; + c->mask |= SD_BUS_CREDS_EGID & mask; } }