diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-05-29 23:33:38 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-05-29 23:35:17 +0200 |
commit | 939b8f14dcd9312140d001b55b4e7a87173682ef (patch) | |
tree | bd67229d635bdff07e0a6b8e3da90d82eb00bd70 /src/shared/capability.c | |
parent | 9246319f1fd9625a4a43883ae660ecd5ae41423a (diff) |
capabilities: when dropping capabilities system-wide also drop them from usermode helpers
This hooks things up with /proc/sys/kernel/usermodehelper/bset and
/proc/sys/kernel/usermodehelper/inheritable.
Diffstat (limited to 'src/shared/capability.c')
-rw-r--r-- | src/shared/capability.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/shared/capability.c b/src/shared/capability.c index 08b7a209da..9b743e86d0 100644 --- a/src/shared/capability.c +++ b/src/shared/capability.c @@ -171,3 +171,54 @@ finish: return r; } + +static int drop_from_file(const char *fn, uint64_t drop) { + int r, k; + uint32_t hi, lo; + uint64_t current, after; + char *p; + + r = read_one_line_file(fn, &p); + if (r < 0) + return r; + + assert_cc(sizeof(hi) == sizeof(unsigned)); + assert_cc(sizeof(lo) == sizeof(unsigned)); + + k = sscanf(p, "%u %u", &lo, &hi); + free(p); + + if (k != 2) + return -EIO; + + current = (uint64_t) lo | ((uint64_t) hi << 32ULL); + after = current & ~drop; + + if (current == after) + return 0; + + lo = (unsigned) (after & 0xFFFFFFFFULL); + hi = (unsigned) ((after >> 32ULL) & 0xFFFFFFFFULL); + + if (asprintf(&p, "%u %u", lo, hi) < 0) + return -ENOMEM; + + r = write_one_line_file(fn, p); + free(p); + + return r; +} + +int capability_bounding_set_drop_usermode(uint64_t drop) { + int r; + + r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", drop); + if (r < 0) + return r; + + r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", drop); + if (r < 0) + return r; + + return r; +} |