diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-12-30 08:42:53 +0100 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-12-30 08:42:53 +0100 |
commit | 34a5d5e52661212c7a145cbab45e70a6df7ba284 (patch) | |
tree | 5488f02fc0ebd7fc76670a01d3e390494c06c7a9 /src/libsystemd/sd-bus/bus-creds.c | |
parent | 180a60bc879ab0554297bc08a7a0b9274b119b55 (diff) |
bus: drop creds->capability_size
The number of available caps can be read from
/proc/sys/kernel/cap_last_cap during runtime. Our helper cap_last_cap()
does that, so there's no reason to remember the size of any capability
cache. We can just pre-allocate arrays with a suitable size for all
available caps and reject any higher caps.
The kernel capability API uses u32 as base so make sure we do the same.
Note that this is specified by POSIX, so it's unlikely to change.
Diffstat (limited to 'src/libsystemd/sd-bus/bus-creds.c')
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 9978ddfa38..55d6fb6b43 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include "util.h" +#include "capability.h" #include "cgroup-util.h" #include "fileio.h" #include "audit.h" @@ -588,10 +589,11 @@ 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) * 4; + if ((unsigned)capability > cap_last_cap()) return 0; return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8))); @@ -638,12 +640,13 @@ _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; + size_t sz, max; unsigned i; assert(c); assert(p); + max = DIV_ROUND_UP(cap_last_cap(), 32U) * 4; p += strspn(p, WHITESPACE); sz = strlen(p); @@ -651,12 +654,13 @@ static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) { return -EINVAL; sz /= 2; + if (sz > max) + return -EINVAL; + if (!c->capability) { - c->capability = new0(uint8_t, sz * 4); + c->capability = new0(uint8_t, max * 4); if (!c->capability) return -ENOMEM; - - c->capability_size = sz * 4; } for (i = 0; i < sz; i ++) { @@ -668,7 +672,7 @@ static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) { if (x < 0 || y < 0) return -EINVAL; - c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y; + c->capability[offset * max + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y; } return 0; @@ -1073,11 +1077,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); } |