]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-capability.c
tree-wide: "<n>bit" → "<n>-bit"
[thirdparty/systemd.git] / src / test / test-capability.c
index c5596bb6c3c2765324630ee4db8bf6a4dbebc6d3..bfdba4f29424d691c6d7cccf64a6bbde020056a5 100644 (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"
 
@@ -161,7 +162,7 @@ static void test_drop_privileges_fail(void) {
 static void test_drop_privileges(void) {
         fork_test(test_drop_privileges_fail);
 
-        if (have_effective_cap(CAP_NET_RAW) == 0) /* The remaining two tests only work if we have CAP_NET_RAW
+        if (have_effective_cap(CAP_NET_RAW) <= 0) /* The remaining two tests only work if we have CAP_NET_RAW
                                                    * in the first place. If we are run in some restricted
                                                    * container environment we might not. */
                 return;
@@ -171,15 +172,15 @@ static void test_drop_privileges(void) {
 }
 
 static void test_have_effective_cap(void) {
-        assert_se(have_effective_cap(CAP_KILL));
-        assert_se(have_effective_cap(CAP_CHOWN));
+        assert_se(have_effective_cap(CAP_KILL) > 0);
+        assert_se(have_effective_cap(CAP_CHOWN) > 0);
 
         assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_KILL)) >= 0);
         assert_se(getuid() == test_uid);
         assert_se(getgid() == test_gid);
 
-        assert_se(have_effective_cap(CAP_KILL));
-        assert_se(!have_effective_cap(CAP_CHOWN));
+        assert_se(have_effective_cap(CAP_KILL) > 0);
+        assert_se(have_effective_cap(CAP_CHOWN) == 0);
 }
 
 static void test_update_inherited_set(void) {
@@ -228,7 +229,7 @@ static void test_apply_ambient_caps(void) {
         assert_se(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) == 0);
 }
 
-static void test_ensure_cap_64bit(void) {
+static void test_ensure_cap_64_bit(void) {
         _cleanup_free_ char *content = NULL;
         unsigned long p = 0;
         int r;
@@ -240,19 +241,69 @@ static void test_ensure_cap_64bit(void) {
 
         assert_se(safe_atolu(content, &p) >= 0);
 
-        /* If caps don't fit into 64bit anymore, we have a problem, fail the test. */
+        /* If caps don't fit into 64-bit anymore, we have a problem, fail the test. */
         assert_se(p <= 63);
 
         /* Also check for the header definition */
         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();
+        test_ensure_cap_64_bit();
 
         test_last_cap_file();
         test_last_cap_probe();
@@ -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;
 }