capability-util: add new capability_get_ambient() helper

This commit is contained in:
Lennart Poettering
2023-02-22 23:45:40 +01:00
parent 66c1e440c7
commit a649419aae
3 changed files with 81 additions and 1 deletions
+25
View File
@@ -605,3 +605,28 @@ int capability_quintet_enforce(const CapabilityQuintet *q) {
return 0;
}
int capability_get_ambient(uint64_t *ret) {
uint64_t a = 0;
int r;
assert(ret);
if (!ambient_capabilities_supported()) {
*ret = 0;
return 0;
}
for (unsigned i = 0; i <= cap_last_cap(); i++) {
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
if (r < 0)
return -errno;
if (r)
a |= UINT64_C(1) << i;
}
*ret = a;
return 1;
}
+2
View File
@@ -83,3 +83,5 @@ static inline bool capability_quintet_is_set(const CapabilityQuintet *q) {
bool capability_quintet_mangle(CapabilityQuintet *q);
int capability_quintet_enforce(const CapabilityQuintet *q);
int capability_get_ambient(uint64_t *ret);
+54 -1
View File
@@ -17,6 +17,7 @@
#include "macro.h"
#include "missing_prctl.h"
#include "parse-util.h"
#include "process-util.h"
#include "string-util.h"
#include "tests.h"
@@ -247,10 +248,60 @@ static void test_ensure_cap_64bit(void) {
assert_cc(CAP_LAST_CAP <= 63);
}
static void test_capability_get_ambient(void) {
uint64_t c;
int r;
assert_se(capability_get_ambient(&c) >= 0);
r = safe_fork("(getambient)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
assert_se(r >= 0);
if (r == 0) {
int x, y;
/* child */
assert_se(capability_get_ambient(&c) >= 0);
x = capability_ambient_set_apply(
(UINT64_C(1) << CAP_MKNOD)|
(UINT64_C(1) << CAP_LINUX_IMMUTABLE),
/* also_inherit= */ true);
assert_se(x >= 0 || ERRNO_IS_PRIVILEGE(x));
assert_se(capability_get_ambient(&c) >= 0);
assert_se(x < 0 || FLAGS_SET(c, UINT64_C(1) << CAP_MKNOD));
assert_se(x < 0 || FLAGS_SET(c, UINT64_C(1) << CAP_LINUX_IMMUTABLE));
assert_se(x < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_SETPCAP));
y = capability_bounding_set_drop(
((UINT64_C(1) << CAP_LINUX_IMMUTABLE)|
(UINT64_C(1) << CAP_SETPCAP)),
/* right_now= */ true);
assert_se(y >= 0 || ERRNO_IS_PRIVILEGE(y));
assert_se(capability_get_ambient(&c) >= 0);
assert_se(x < 0 || y < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_MKNOD));
assert_se(x < 0 || y < 0 || FLAGS_SET(c, UINT64_C(1) << CAP_LINUX_IMMUTABLE));
assert_se(x < 0 || y < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_SETPCAP));
y = capability_bounding_set_drop(
(UINT64_C(1) << CAP_SETPCAP),
/* right_now= */ true);
assert_se(y >= 0 || ERRNO_IS_PRIVILEGE(y));
assert_se(capability_get_ambient(&c) >= 0);
assert_se(x < 0 || y < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_MKNOD));
assert_se(x < 0 || y < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_LINUX_IMMUTABLE));
assert_se(x < 0 || y < 0 || !FLAGS_SET(c, UINT64_C(1) << CAP_SETPCAP));
_exit(EXIT_SUCCESS);
}
}
int main(int argc, char *argv[]) {
bool run_ambient;
test_setup_logging(LOG_INFO);
test_setup_logging(LOG_DEBUG);
test_ensure_cap_64bit();
@@ -275,5 +326,7 @@ int main(int argc, char *argv[]) {
if (run_ambient)
fork_test(test_apply_ambient_caps);
test_capability_get_ambient();
return 0;
}