summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libsystemd/sd-bus/bus-control.c8
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c21
-rw-r--r--src/libsystemd/sd-bus/bus-creds.h1
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c8
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;