diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 13aa6fee438..8cc75c06c87 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -405,7 +405,7 @@ bool capability_quintet_mangle(CapabilityQuintet *q) { combined = q->effective | q->bounding | q->inheritable | q->permitted; - ambient_supported = q->ambient != UINT64_MAX; + ambient_supported = q->ambient != CAP_MASK_UNSET; if (ambient_supported) combined |= q->ambient; @@ -437,7 +437,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { _cleanup_cap_free_ cap_t c = NULL, modified = NULL; int r; - if (q->ambient != UINT64_MAX) { + if (q->ambient != CAP_MASK_UNSET) { bool changed = false; c = cap_get_proc(); @@ -479,7 +479,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { return r; } - if (q->inheritable != UINT64_MAX || q->permitted != UINT64_MAX || q->effective != UINT64_MAX) { + if (q->inheritable != CAP_MASK_UNSET || q->permitted != CAP_MASK_UNSET || q->effective != CAP_MASK_UNSET) { bool changed = false; if (!c) { @@ -492,7 +492,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { uint64_t m = UINT64_C(1) << i; cap_value_t cv = (cap_value_t) i; - if (q->inheritable != UINT64_MAX) { + if (q->inheritable != CAP_MASK_UNSET) { cap_flag_value_t old_value, new_value; if (cap_get_flag(c, cv, CAP_INHERITABLE, &old_value) < 0) { @@ -515,7 +515,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { } } - if (q->permitted != UINT64_MAX) { + if (q->permitted != CAP_MASK_UNSET) { cap_flag_value_t old_value, new_value; if (cap_get_flag(c, cv, CAP_PERMITTED, &old_value) < 0) { @@ -535,7 +535,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { } } - if (q->effective != UINT64_MAX) { + if (q->effective != CAP_MASK_UNSET) { cap_flag_value_t old_value, new_value; if (cap_get_flag(c, cv, CAP_EFFECTIVE, &old_value) < 0) { @@ -559,7 +559,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { if (changed) { /* In order to change the bounding caps, we need to keep CAP_SETPCAP for a bit * longer. Let's add it to our list hence for now. */ - if (q->bounding != UINT64_MAX) { + if (q->bounding != CAP_MASK_UNSET) { cap_value_t cv = CAP_SETPCAP; modified = cap_dup(c); @@ -587,7 +587,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { } } - if (q->bounding != UINT64_MAX) { + if (q->bounding != CAP_MASK_UNSET) { r = capability_bounding_set_drop(q->bounding, false); if (r < 0) return r; diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h index 4d1b0521f40..48e8db35f68 100644 --- a/src/basic/capability-util.h +++ b/src/basic/capability-util.h @@ -9,7 +9,11 @@ #include "macro.h" #include "missing_capability.h" -#define CAP_ALL UINT64_MAX +/* Special marker used when storing a capabilities mask as "unset" */ +#define CAP_MASK_UNSET UINT64_MAX + +/* All possible capabilities bits on */ +#define CAP_MASK_ALL UINT64_C(0x7fffffffffffffff) unsigned cap_last_cap(void); int have_effective_cap(int value); @@ -59,14 +63,14 @@ typedef struct CapabilityQuintet { assert_cc(CAP_LAST_CAP < 64); -#define CAPABILITY_QUINTET_NULL { UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX } +#define CAPABILITY_QUINTET_NULL { CAP_MASK_UNSET, CAP_MASK_UNSET, CAP_MASK_UNSET, CAP_MASK_UNSET, CAP_MASK_UNSET } static inline bool capability_quintet_is_set(const CapabilityQuintet *q) { - return q->effective != UINT64_MAX || - q->bounding != UINT64_MAX || - q->inheritable != UINT64_MAX || - q->permitted != UINT64_MAX || - q->ambient != UINT64_MAX; + return q->effective != CAP_MASK_UNSET || + q->bounding != CAP_MASK_UNSET || + q->inheritable != CAP_MASK_UNSET || + q->permitted != CAP_MASK_UNSET || + q->ambient != CAP_MASK_UNSET; } /* Mangles the specified caps quintet taking the current bounding set into account: diff --git a/src/core/execute.c b/src/core/execute.c index 5116a73617a..f38a5a41fe2 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -5466,7 +5466,7 @@ void exec_context_init(ExecContext *c) { for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) c->directories[t].mode = 0755; c->timeout_clean_usec = USEC_INFINITY; - c->capability_bounding_set = CAP_ALL; + c->capability_bounding_set = CAP_MASK_UNSET; assert_cc(NAMESPACE_FLAGS_INITIAL != NAMESPACE_FLAGS_ALL); c->restrict_namespaces = NAMESPACE_FLAGS_INITIAL; c->log_level_max = -1; @@ -6192,7 +6192,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { fprintf(f, "%sSecure Bits: %s\n", prefix, str); } - if (c->capability_bounding_set != CAP_ALL) { + if (c->capability_bounding_set != CAP_MASK_UNSET) { _cleanup_free_ char *str = NULL; r = capability_set_to_string(c->capability_bounding_set, &str); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index ec782703a75..d4a874eafa5 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1886,7 +1886,7 @@ int config_parse_capability_set( void *userdata) { uint64_t *capability_set = ASSERT_PTR(data); - uint64_t sum = 0, initial = 0; + uint64_t sum = 0, initial, def; bool invert = false; int r; @@ -1899,9 +1899,11 @@ int config_parse_capability_set( rvalue++; } - if (streq(lvalue, "CapabilityBoundingSet")) - initial = CAP_ALL; /* initialized to all bits on */ - /* else "AmbientCapabilities" initialized to all bits off */ + if (streq(lvalue, "CapabilityBoundingSet")) { + initial = CAP_MASK_ALL; /* initialized to all bits on */ + def = CAP_MASK_UNSET; /* not set */ + } else + def = initial = 0; /* All bits off */ r = capability_set_from_string(rvalue, &sum); if (r < 0) { @@ -1909,7 +1911,7 @@ int config_parse_capability_set( return 0; } - if (sum == 0 || *capability_set == initial) + if (sum == 0 || *capability_set == def) /* "", "~" or uninitialized data -> replace */ *capability_set = invert ? ~sum : sum; else { diff --git a/src/core/main.c b/src/core/main.c index f28448f9e43..1af9b8b5050 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2458,7 +2458,7 @@ static void reset_arguments(void) { arg_manager_environment = strv_free(arg_manager_environment); rlimit_free_all(arg_default_rlimit); - arg_capability_bounding_set = CAP_ALL; + arg_capability_bounding_set = CAP_MASK_UNSET; arg_no_new_privs = false; arg_timer_slack_nsec = NSEC_INFINITY; arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;