diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd/sd-bus/bus-control.c | 8 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.c | 21 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.h | 1 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 8 |
4 files changed, 25 insertions, 13 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index e86546c343..b2394db3eb 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) { @@ -520,8 +521,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; 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); } diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h index 48453e2afd..2480a4a0b1 100644 --- a/src/libsystemd/sd-bus/bus-creds.h +++ b/src/libsystemd/sd-bus/bus-creds.h @@ -61,7 +61,6 @@ struct sd_bus_creds { char *slice; uint8_t *capability; - size_t capability_size; uint32_t audit_session_id; uid_t audit_login_uid; diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index d9252b2560..eeb4a518d1 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -32,6 +32,7 @@ #include "util.h" #include "strv.h" #include "memfd-util.h" +#include "capability.h" #include "cgroup-util.h" #include "fileio.h" @@ -673,8 +674,13 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { break; case KDBUS_ITEM_CAPS: + if (d->caps.last_cap != cap_last_cap() || + d->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(d->caps.last_cap, 32U) * 4 * 4) { + r = -EBADMSG; + goto fail; + } + m->creds.capability = (uint8_t *) d->caps.caps; - m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps); m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask; break; |