The kernel provides capabilities as a u32 array, sd-bus uses an u8 array.
This works fine on little-endian as both are encoded the same way.
However, this fails on big-endian if we do not perform sufficient
byte-swapping on each u32 entry.
This patch makes sd-bus use u32, too. We avoid changing any kernel
provided data so we can keep pointing into kdbus pool buffers which
contain u32 arrays.
+#include <linux/capability.h>
#include "util.h"
#include "capability.h"
#include "util.h"
#include "capability.h"
assert(capability >= 0);
assert(c->capability);
assert(capability >= 0);
assert(c->capability);
- sz = DIV_ROUND_UP(cap_last_cap(), 32U) * 4;
+ sz = DIV_ROUND_UP(cap_last_cap(), 32U);
if ((unsigned)capability > cap_last_cap())
return 0;
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) {
}
_public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
size_t sz, max;
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
size_t sz, max;
- max = DIV_ROUND_UP(cap_last_cap(), 32U) * 4;
+ max = DIV_ROUND_UP(cap_last_cap(), 32U);
p += strspn(p, WHITESPACE);
sz = strlen(p);
p += strspn(p, WHITESPACE);
sz = strlen(p);
if (sz > max)
return -EINVAL;
if (!c->capability) {
if (sz > max)
return -EINVAL;
if (!c->capability) {
- c->capability = new0(uint8_t, max * 4);
+ c->capability = new0(uint32_t, max * 4);
if (!c->capability)
return -ENOMEM;
}
for (i = 0; i < sz; i ++) {
if (!c->capability)
return -ENOMEM;
}
for (i = 0; i < sz; i ++) {
- 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 * max + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
+ v = (v << 4) | t;
+ }
+
+ c->capability[offset * max + (sz - i - 1)] = v;
char *user_unit;
char *slice;
char *user_unit;
char *slice;
uint32_t audit_session_id;
uid_t audit_login_uid;
uint32_t audit_session_id;
uid_t audit_login_uid;
- m->creds.capability = (uint8_t *) d->caps.caps;
+ m->creds.capability = d->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;
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;