summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorIsmo Puustinen <ismo.puustinen@intel.com>2016-01-08 00:00:04 +0200
committerIsmo Puustinen <ismo.puustinen@intel.com>2016-01-12 12:14:50 +0200
commita103496ca585e22bb5e386e3238b468d133f5659 (patch)
tree7d9b33722f54c969fc145f7d5fe31afe13aff09c /src/basic
parentf466acdc633fc496961eff0c7f66501f4588e5b6 (diff)
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.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/capability-util.c16
-rw-r--r--src/basic/capability-util.h12
2 files changed, 18 insertions, 10 deletions
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c
index fef722b6f2..881f0f671e 100644
--- a/src/basic/capability-util.c
+++ b/src/basic/capability-util.c
@@ -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");
diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h
index 6bbf7318fd..f6a48b7916 100644
--- a/src/basic/capability-util.h
+++ b/src/basic/capability-util.h
@@ -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;
+}