예제 #1
0
static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
        size_t sz;

        assert(c);
        assert(capability >= 0);
        assert(c->capability);

        if ((unsigned) capability > cap_last_cap())
                return 0;

        sz = DIV_ROUND_UP(cap_last_cap(), 32U);

        return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
}
예제 #2
0
/* verify cap_last_cap() against /proc/sys/kernel/cap_last_cap */
static void test_last_cap_file(void) {
        _cleanup_free_ char *content = NULL;
        unsigned long val = 0;
        int r;

        r = read_one_line_file("/proc/sys/kernel/cap_last_cap", &content);
        assert_se(r >= 0);

        r = safe_atolu(content, &val);
        assert_se(r >= 0);
        assert_se(val != 0);
        assert_se(val == cap_last_cap());
}
예제 #3
0
/* verify cap_last_cap() against syscall probing */
static void test_last_cap_probe(void) {
        unsigned long p = (unsigned long)CAP_LAST_CAP;

        if (prctl(PR_CAPBSET_READ, p) < 0) {
                for (p--; p > 0; p --)
                        if (prctl(PR_CAPBSET_READ, p) >= 0)
                                break;
        } else {
                for (;; p++)
                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
                                break;
        }

        assert_se(p != 0);
        assert_se(p == cap_last_cap());
}
예제 #4
0
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
        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 % 8 != 0)
                return -EINVAL;

        sz /= 8;
        if (sz > max)
                return -EINVAL;

        if (!c->capability) {
                c->capability = new0(uint32_t, max * 4);
                if (!c->capability)
                        return -ENOMEM;
        }

        for (i = 0; i < sz; i ++) {
                uint32_t v = 0;

                for (j = 0; j < 8; ++j) {
                        int t;

                        t = unhexchar(*p++);
                        if (t < 0)
                                return -EINVAL;

                        v = (v << 4) | t;
                }

                c->capability[offset * max + (sz - i - 1)] = v;
        }

        return 0;
}