-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdio.h>
#include "util.h"
int have_effective_cap(int value) {
- _cleanup_cap_free_ cap_t cap;
+ _cleanup_cap_free_ cap_t cap = NULL;
cap_flag_value_t fv;
cap = cap_get_proc();
return 0;
}
-int capability_bounding_set_drop(uint64_t keep, bool right_now) {
- _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL;
+int capability_gain_cap_setpcap(cap_t *ret_before_caps) {
+ _cleanup_cap_free_ cap_t caps = NULL;
cap_flag_value_t fv;
- int r;
-
- /* If we are run as PID 1 we will lack CAP_SETPCAP by default
- * in the effective set (yes, the kernel drops that when
- * executing init!), so get it back temporarily so that we can
- * call PR_CAPBSET_DROP. */
-
- before_cap = cap_get_proc();
- if (!before_cap)
+ caps = cap_get_proc();
+ if (!caps)
return -errno;
- if (cap_get_flag(before_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0)
+ if (cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0)
return -errno;
if (fv != CAP_SET) {
_cleanup_cap_free_ cap_t temp_cap = NULL;
static const cap_value_t v = CAP_SETPCAP;
- temp_cap = cap_dup(before_cap);
+ temp_cap = cap_dup(caps);
if (!temp_cap)
return -errno;
log_debug_errno(errno, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m");
/* If we didn't manage to acquire the CAP_SETPCAP bit, we continue anyway, after all this just means
- * we'll fail later, when we actually intend to drop some capabilities. */
+ * we'll fail later, when we actually intend to drop some capabilities or try to set securebits. */
}
+ if (ret_before_caps)
+ /* Return the capabilities as they have been before setting CAP_SETPCAP */
+ *ret_before_caps = TAKE_PTR(caps);
+
+ return 0;
+}
+
+int capability_bounding_set_drop(uint64_t keep, bool right_now) {
+ _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL;
+ int r;
+
+ /* If we are run as PID 1 we will lack CAP_SETPCAP by default
+ * in the effective set (yes, the kernel drops that when
+ * executing init!), so get it back temporarily so that we can
+ * call PR_CAPBSET_DROP. */
+
+ r = capability_gain_cap_setpcap(&before_cap);
+ if (r < 0)
+ return r;
after_cap = cap_dup(before_cap);
if (!after_cap)
combined = q->effective | q->bounding | q->inheritable | q->permitted;
- ambient_supported = q->ambient != (uint64_t) -1;
+ ambient_supported = q->ambient != UINT64_MAX;
if (ambient_supported)
combined |= q->ambient;
_cleanup_cap_free_ cap_t c = NULL, modified = NULL;
int r;
- if (q->ambient != (uint64_t) -1) {
+ if (q->ambient != UINT64_MAX) {
bool changed = false;
c = cap_get_proc();
return r;
}
- if (q->inheritable != (uint64_t) -1 || q->permitted != (uint64_t) -1 || q->effective != (uint64_t) -1) {
+ if (q->inheritable != UINT64_MAX || q->permitted != UINT64_MAX || q->effective != UINT64_MAX) {
bool changed = false;
if (!c) {
uint64_t m = UINT64_C(1) << i;
cap_value_t cv = (cap_value_t) i;
- if (q->inheritable != (uint64_t) -1) {
+ if (q->inheritable != UINT64_MAX) {
cap_flag_value_t old_value, new_value;
if (cap_get_flag(c, cv, CAP_INHERITABLE, &old_value) < 0) {
}
}
- if (q->permitted != (uint64_t) -1) {
+ if (q->permitted != UINT64_MAX) {
cap_flag_value_t old_value, new_value;
if (cap_get_flag(c, cv, CAP_PERMITTED, &old_value) < 0) {
}
}
- if (q->effective != (uint64_t) -1) {
+ if (q->effective != UINT64_MAX) {
cap_flag_value_t old_value, new_value;
if (cap_get_flag(c, cv, CAP_EFFECTIVE, &old_value) < 0) {
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_t) -1) {
+ if (q->bounding != UINT64_MAX) {
cap_value_t cv = CAP_SETPCAP;
modified = cap_dup(c);
}
}
- if (q->bounding != (uint64_t) -1) {
+ if (q->bounding != UINT64_MAX) {
r = capability_bounding_set_drop(q->bounding, false);
if (r < 0)
return r;