X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-creds.c;h=54e76ab6c4e3395ef98edc76d69b04a5c92f62f0;hb=7d9fcc2bf6869993e5f38d5eb183fb59e8a52816;hp=43315b5b50207d44cf126765ea08f5467174f0d9;hpb=a6ede528c478177821423f1e61e625030a6602c0;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 43315b5b5..54e76ab6c 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -20,8 +20,10 @@ ***/ #include +#include #include "util.h" +#include "capability.h" #include "cgroup-util.h" #include "fileio.h" #include "audit.h" @@ -51,10 +53,14 @@ void bus_creds_done(sd_bus_creds *c) { free(c->slice); free(c->unescaped_description); - strv_free(c->cmdline_array); - strv_free(c->well_known_names); + free(c->well_known_names); /* note that this is an strv, but + * we only free the array, not the + * strings the array points to. The + * full strv we only free if + * c->allocated is set, see + * below. */ - free(c->supplementary_gids); + strv_free(c->cmdline_array); } _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { @@ -85,8 +91,6 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { c->n_ref--; if (c->n_ref == 0) { - bus_creds_done(c); - free(c->comm); free(c->tid_comm); free(c->exe); @@ -97,6 +101,13 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { free(c->unique_name); free(c->cgroup_root); free(c->description); + free(c->supplementary_gids); + + strv_free(c->well_known_names); + c->well_known_names = NULL; + + bus_creds_done(c); + free(c); } } else { @@ -285,18 +296,6 @@ _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) { return 0; } -_public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) { - assert_return(c, -EINVAL); - assert_return(usec, -EINVAL); - - if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME)) - return -ENODATA; - - assert(c->pid_starttime > 0); - *usec = c->pid_starttime; - return 0; -} - _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); @@ -542,6 +541,28 @@ _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_kno if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)) return -ENODATA; + /* As a special hack we return the bus driver as well-known + * names list when this is requested. */ + if (c->well_known_names_driver) { + static const char* const wkn[] = { + "org.freedesktop.DBus", + NULL + }; + + *well_known_names = (char**) wkn; + return 0; + } + + if (c->well_known_names_local) { + static const char* const wkn[] = { + "org.freedesktop.DBus.Local", + NULL + }; + + *well_known_names = (char**) wkn; + return 0; + } + *well_known_names = c->well_known_names; return 0; } @@ -569,13 +590,14 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { size_t sz; assert(c); + assert(capability >= 0); assert(c->capability); - sz = c->capability_size / 4; - if ((size_t) capability >= sz*8) + sz = DIV_ROUND_UP(cap_last_cap(), 32U); + if ((unsigned)capability > cap_last_cap()) return 0; - return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8))); + return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability)); } _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { @@ -619,37 +641,43 @@ _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) { } static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) { - size_t sz; - unsigned i; + size_t sz, max; + unsigned i, j; assert(c); assert(p); + max = DIV_ROUND_UP(cap_last_cap(), 32U); p += strspn(p, WHITESPACE); sz = strlen(p); - if (sz % 2 != 0) + if (sz % 8 != 0) + return -EINVAL; + + sz /= 8; + if (sz > max) return -EINVAL; - sz /= 2; if (!c->capability) { - c->capability = new0(uint8_t, sz * 4); + c->capability = new0(uint32_t, max * 4); if (!c->capability) return -ENOMEM; - - c->capability_size = sz * 4; } for (i = 0; i < sz; i ++) { - int x, y; + uint32_t v = 0; - x = unhexchar(p[i*2]); - y = unhexchar(p[i*2+1]); + for (j = 0; j < 8; ++j) { + int t; - if (x < 0 || y < 0) - return -EINVAL; + t = unhexchar(*p++); + if (t < 0) + return -EINVAL; - c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y; + v = (v << 4) | t; + } + + c->capability[offset * max + (sz - i - 1)] = v; } return 0; @@ -828,19 +856,6 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { } } - if (missing & (SD_BUS_CREDS_PID_STARTTIME)) { - unsigned long long st; - - r = get_starttime_of_pid(pid, &st); - 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) { const char *p; @@ -1021,11 +1036,6 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) n->mask |= SD_BUS_CREDS_TID; } - if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) { - n->pid_starttime = c->pid_starttime; - n->mask |= SD_BUS_CREDS_PID_STARTTIME; - } - if (c->mask & mask & SD_BUS_CREDS_COMM) { n->comm = strdup(c->comm); if (!n->comm) @@ -1072,11 +1082,10 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) { - n->capability = memdup(c->capability, c->capability_size); + n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4); if (!n->capability) return -ENOMEM; - n->capability_size = c->capability_size; n->mask |= c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS); }