]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-userns-restrict: Migrate to new assertion macros
authorDaan De Meyer <daan@amutable.com>
Mon, 9 Feb 2026 20:58:48 +0000 (21:58 +0100)
committerDaan De Meyer <daan@amutable.com>
Thu, 19 Feb 2026 20:33:11 +0000 (21:33 +0100)
We also inline the test functions so we get proper line information
in the failure coredumps.

src/nsresourced/test-userns-restrict.c

index b40c6551bca949e08541376e61a926cf1ff21f37..dc06b7b08f75b2284dade2400a2063fdd327439e 100644 (file)
 
 #include "errno-util.h"
 #include "fd-util.h"
-#include "log.h"
-#include "main-func.h"
 #include "namespace-util.h"
 #include "pidref.h"
 #include "process-util.h"
 #include "rm-rf.h"
+#include "tests.h"
 #include "tmpfile-util.h"
 #include "userns-restrict.h"
 
 static int make_tmpfs_fsmount(void) {
         _cleanup_close_ int fsfd = -EBADF, mntfd = -EBADF;
 
-        fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
-        assert_se(fsfd >= 0);
-        assert_se(fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0) >= 0);
+        fsfd = ASSERT_OK_ERRNO(fsopen("tmpfs", FSOPEN_CLOEXEC));
+        ASSERT_OK_ERRNO(fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
 
-        mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, 0);
-        assert_se(mntfd >= 0);
+        mntfd = ASSERT_OK_ERRNO(fsmount(fsfd, FSMOUNT_CLOEXEC, 0));
 
         return TAKE_FD(mntfd);
 }
 
-static void test_works_reg(int parent_fd, const char *fname) {
-        _cleanup_close_ int fd = -EBADF;
+static struct userns_restrict_bpf *bpf_obj = NULL;
+STATIC_DESTRUCTOR_REGISTER(bpf_obj, userns_restrict_bpf_freep);
 
-        fd = openat(parent_fd, fname, O_RDWR|O_CREAT|O_CLOEXEC, 0666);
-        assert_se(fd >= 0);
-}
-
-static void test_fails_reg(int parent_fd, const char *fname) {
-        errno = 0;
-        assert_se(openat(parent_fd, fname, O_RDWR|O_CREAT|O_CLOEXEC, 0666) < 0);
-        assert_se(errno == EPERM);
-}
+static int intro(void) {
+        int r;
 
-static void test_works_dir(int parent_fd, const char *fname) {
-        assert_se(mkdirat(parent_fd, fname, 0666) >= 0);
-}
+        r = userns_restrict_install(/* pin= */ false, &bpf_obj);
+        if (ERRNO_IS_NOT_SUPPORTED(r))
+                return log_tests_skipped("LSM-BPF logic not supported");
+        if (ERRNO_IS_PRIVILEGE(r))
+                return log_tests_skipped("Lacking privileges");
+        ASSERT_OK(r);
 
-static void test_fails_dir(int parent_fd, const char *fname) {
-        errno = 0;
-        assert_se(mkdirat(parent_fd, fname, 0666) < 0);
-        assert_se(errno == EPERM);
+        return 0;
 }
 
-static int run(int argc, char *argv[]) {
-        _cleanup_(userns_restrict_bpf_freep) struct userns_restrict_bpf *obj = NULL;
+TEST(userns_restrict) {
         _cleanup_close_ int userns_fd = -EBADF, host_fd1 = -EBADF, host_tmpfs = -EBADF, afd = -EBADF, bfd = -EBADF;
         _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
         _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
         int r;
 
-        log_set_max_level(LOG_DEBUG);
-        log_setup();
-
-        r = userns_restrict_install(/* pin= */ false, &obj);
-        if (ERRNO_IS_NOT_SUPPORTED(r)) {
-                log_notice("Skipping test, LSM-BPF logic not supported.");
-                return EXIT_TEST_SKIP;
-        }
-        if (ERRNO_IS_PRIVILEGE(r)) {
-                log_notice("Skipping test, lacking privileges.");
-                return EXIT_TEST_SKIP;
-        }
-        if (r < 0)
-                return r;
-
-        assert_se(mkdtemp_malloc(NULL, &t) >= 0);
-
-        host_fd1 = open(t, O_DIRECTORY|O_CLOEXEC);
-        assert_se(host_fd1 >= 0);
-
-        host_tmpfs = make_tmpfs_fsmount();
-        assert_se(host_tmpfs >= 0);
+        ASSERT_OK(mkdtemp_malloc(NULL, &t));
 
-        userns_fd = userns_acquire("0 0 1", "0 0 1", /* setgroups_deny= */ true);
-        if (userns_fd < 0)
-                return log_error_errno(userns_fd, "Failed to make user namespace: %m");
+        host_fd1 = ASSERT_OK_ERRNO(open(t, O_DIRECTORY|O_CLOEXEC));
+        host_tmpfs = ASSERT_OK(make_tmpfs_fsmount());
+        userns_fd = ASSERT_OK(userns_acquire("0 0 1", "0 0 1", /* setgroups_deny= */ true));
 
-        r = userns_restrict_put_by_fd(
-                        obj,
+        ASSERT_OK(userns_restrict_put_by_fd(
+                        bpf_obj,
                         userns_fd,
                         /* replace= */ true,
                         /* mount_fds= */ NULL,
-                        /* n_mount_fds= */ 0);
-        if (r < 0)
-                return log_error_errno(r, "Failed to restrict user namespace: %m");
+                        /* n_mount_fds= */ 0));
 
-        afd = eventfd(0, EFD_CLOEXEC);
-        bfd = eventfd(0, EFD_CLOEXEC);
+        afd = ASSERT_OK_ERRNO(eventfd(0, EFD_CLOEXEC));
+        bfd = ASSERT_OK_ERRNO(eventfd(0, EFD_CLOEXEC));
 
-        assert_se(afd >= 0 && bfd >= 0);
-
-        r = pidref_safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pidref);
-        assert_se(r >= 0);
+        r = ASSERT_OK(pidref_safe_fork("(test)", FORK_DEATHSIG_SIGKILL, &pidref));
         if (r == 0) {
                 _cleanup_close_ int private_tmpfs = -EBADF;
 
-                assert_se(setns(userns_fd, CLONE_NEWUSER) >= 0);
-                assert_se(unshare(CLONE_NEWNS) >= 0);
+                ASSERT_OK_ERRNO(setns(userns_fd, CLONE_NEWUSER));
+                ASSERT_OK_ERRNO(unshare(CLONE_NEWNS));
 
                 /* Allocate tmpfs locally */
                 private_tmpfs = make_tmpfs_fsmount();
 
                 /* These two host mounts should be inaccessible */
-                test_fails_reg(host_fd1, "test");
-                test_fails_reg(host_tmpfs, "xxx");
-                test_fails_dir(host_fd1, "test2");
-                test_fails_dir(host_tmpfs, "xxx2");
+                ASSERT_ERROR_ERRNO(openat(host_fd1, "test", O_RDWR|O_CREAT|O_CLOEXEC, 0666), EPERM);
+                ASSERT_ERROR_ERRNO(openat(host_tmpfs, "xxx", O_RDWR|O_CREAT|O_CLOEXEC, 0666), EPERM);
+                ASSERT_ERROR_ERRNO(mkdirat(host_fd1, "test2", 0666), EPERM);
+                ASSERT_ERROR_ERRNO(mkdirat(host_tmpfs, "xxx2", 0666), EPERM);
 
                 /* But this mount created locally should be fine */
-                test_works_reg(private_tmpfs, "yyy");
-                test_works_dir(private_tmpfs, "yyy2");
+                safe_close(ASSERT_OK_ERRNO(openat(private_tmpfs, "yyy", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                ASSERT_OK_ERRNO(mkdirat(private_tmpfs, "yyy2", 0666));
 
                 /* Let's sync with the parent, so that it allowlists more stuff for us */
-                assert_se(eventfd_write(afd, 1) >= 0);
+                ASSERT_OK_ERRNO(eventfd_write(afd, 1));
                 uint64_t x;
-                assert_se(eventfd_read(bfd, &x) >= 0);
+                ASSERT_OK_ERRNO(eventfd_read(bfd, &x));
 
                 /* And now we should also have access to the host tmpfs */
-                test_works_reg(host_tmpfs, "zzz");
-                test_works_reg(private_tmpfs, "aaa");
-                test_works_dir(host_tmpfs, "zzz2");
-                test_works_dir(private_tmpfs, "aaa2");
+                safe_close(ASSERT_OK_ERRNO(openat(host_tmpfs, "zzz", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                safe_close(ASSERT_OK_ERRNO(openat(private_tmpfs, "aaa", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                ASSERT_OK_ERRNO(mkdirat(host_tmpfs, "zzz2", 0666));
+                ASSERT_OK_ERRNO(mkdirat(private_tmpfs, "aaa2", 0666));
 
                 /* But this one should still fail */
-                test_fails_reg(host_fd1, "bbb");
-                test_fails_dir(host_fd1, "bbb2");
+                ASSERT_ERROR_ERRNO(openat(host_fd1, "bbb", O_RDWR|O_CREAT|O_CLOEXEC, 0666), EPERM);
+                ASSERT_ERROR_ERRNO(mkdirat(host_fd1, "bbb2", 0666), EPERM);
 
                 /* Sync again, to get more stuff allowlisted */
-                assert_se(eventfd_write(afd, 1) >= 0);
-                assert_se(eventfd_read(bfd, &x) >= 0);
+                ASSERT_OK_ERRNO(eventfd_write(afd, 1));
+                ASSERT_OK_ERRNO(eventfd_read(bfd, &x));
 
                 /* Everything should now be allowed */
-                test_works_reg(host_tmpfs, "ccc");
-                test_works_reg(host_fd1, "ddd");
-                test_works_reg(private_tmpfs, "eee");
-                test_works_dir(host_tmpfs, "ccc2");
-                test_works_reg(host_fd1, "ddd2");
-                test_works_dir(private_tmpfs, "eee2");
+                safe_close(ASSERT_OK_ERRNO(openat(host_tmpfs, "ccc", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                safe_close(ASSERT_OK_ERRNO(openat(host_fd1, "ddd", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                safe_close(ASSERT_OK_ERRNO(openat(private_tmpfs, "eee", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                ASSERT_OK_ERRNO(mkdirat(host_tmpfs, "ccc2", 0666));
+                safe_close(ASSERT_OK_ERRNO(openat(host_fd1, "ddd2", O_RDWR|O_CREAT|O_CLOEXEC, 0666)));
+                ASSERT_OK_ERRNO(mkdirat(private_tmpfs, "eee2", 0666));
 
                 _exit(EXIT_SUCCESS);
         }
 
         uint64_t x;
-        assert_se(eventfd_read(afd, &x) >= 0);
+        ASSERT_OK_ERRNO(eventfd_read(afd, &x));
 
-        r = userns_restrict_put_by_fd(
-                        obj,
+        ASSERT_OK(userns_restrict_put_by_fd(
+                        bpf_obj,
                         userns_fd,
                         /* replace= */ false,
                         &host_tmpfs,
-                        1);
-        if (r < 0)
-                return log_error_errno(r, "Failed to loosen user namespace: %m");
-
-        assert_se(eventfd_write(bfd, 1) >= 0);
+                        1));
 
-        assert_se(eventfd_read(afd, &x) >= 0);
+        ASSERT_OK_ERRNO(eventfd_write(bfd, 1));
+        ASSERT_OK_ERRNO(eventfd_read(afd, &x));
 
-        r = userns_restrict_put_by_fd(
-                        obj,
+        ASSERT_OK(userns_restrict_put_by_fd(
+                        bpf_obj,
                         userns_fd,
                         /* replace= */ false,
                         &host_fd1,
-                        1);
-        if (r < 0)
-                return log_error_errno(r, "Failed to loosen user namespace: %m");
+                        1));
 
-        assert_se(eventfd_write(bfd, 1) >= 0);
+        ASSERT_OK_ERRNO(eventfd_write(bfd, 1));
 
-        assert_se(pidref_wait_for_terminate_and_check("(test)", &pidref, WAIT_LOG) >= 0);
-
-        return 0;
+        ASSERT_OK(pidref_wait_for_terminate_and_check("(test)", &pidref, WAIT_LOG));
 }
 
-DEFINE_MAIN_FUNCTION(run);
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);