capabilities: keep bounding set in non-inverted format.
Change the capability bounding set parser and logic so that the bounding set is kept as a positive set internally. This means that the set reflects those capabilities that we want to keep instead of drop.
This commit is contained in:
@@ -96,7 +96,7 @@ unsigned long cap_last_cap(void) {
|
||||
return p;
|
||||
}
|
||||
|
||||
int capability_bounding_set_drop(uint64_t drop, bool right_now) {
|
||||
int capability_bounding_set_drop(uint64_t keep, bool right_now) {
|
||||
_cleanup_cap_free_ cap_t after_cap = NULL;
|
||||
cap_flag_value_t fv;
|
||||
unsigned long i;
|
||||
@@ -137,7 +137,7 @@ int capability_bounding_set_drop(uint64_t drop, bool right_now) {
|
||||
|
||||
for (i = 0; i <= cap_last_cap(); i++) {
|
||||
|
||||
if (drop & ((uint64_t) 1ULL << (uint64_t) i)) {
|
||||
if (!(keep & (UINT64_C(1) << i))) {
|
||||
cap_value_t v;
|
||||
|
||||
/* Drop it from the bounding set */
|
||||
@@ -176,7 +176,7 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int drop_from_file(const char *fn, uint64_t drop) {
|
||||
static int drop_from_file(const char *fn, uint64_t keep) {
|
||||
int r, k;
|
||||
uint32_t hi, lo;
|
||||
uint64_t current, after;
|
||||
@@ -196,7 +196,7 @@ static int drop_from_file(const char *fn, uint64_t drop) {
|
||||
return -EIO;
|
||||
|
||||
current = (uint64_t) lo | ((uint64_t) hi << 32ULL);
|
||||
after = current & ~drop;
|
||||
after = current & keep;
|
||||
|
||||
if (current == after)
|
||||
return 0;
|
||||
@@ -213,14 +213,14 @@ static int drop_from_file(const char *fn, uint64_t drop) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int capability_bounding_set_drop_usermode(uint64_t drop) {
|
||||
int capability_bounding_set_drop_usermode(uint64_t keep) {
|
||||
int r;
|
||||
|
||||
r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", drop);
|
||||
r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", keep);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", drop);
|
||||
r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", keep);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -257,7 +257,7 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
|
||||
return log_error_errno(errno, "Failed to disable keep capabilities flag: %m");
|
||||
|
||||
/* Drop all caps from the bounding set, except the ones we want */
|
||||
r = capability_bounding_set_drop(~keep_capabilities, true);
|
||||
r = capability_bounding_set_drop(keep_capabilities, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to drop capabilities: %m");
|
||||
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
|
||||
#define CAP_ALL (uint64_t) -1
|
||||
|
||||
unsigned long cap_last_cap(void);
|
||||
int have_effective_cap(int value);
|
||||
int capability_bounding_set_drop(uint64_t drop, bool right_now);
|
||||
int capability_bounding_set_drop_usermode(uint64_t drop);
|
||||
int capability_bounding_set_drop(uint64_t keep, bool right_now);
|
||||
int capability_bounding_set_drop_usermode(uint64_t keep);
|
||||
|
||||
int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities);
|
||||
|
||||
@@ -46,3 +48,9 @@ static inline void cap_free_charpp(char **p) {
|
||||
cap_free(*p);
|
||||
}
|
||||
#define _cleanup_cap_free_charp_ _cleanup_(cap_free_charpp)
|
||||
|
||||
static inline bool cap_test_all(uint64_t caps) {
|
||||
uint64_t m;
|
||||
m = (UINT64_C(1) << (cap_last_cap() + 1)) - 1;
|
||||
return (caps & m) == m;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user