From 058a07635f3ff70cc99943dcf4f2a079bc9c28b9 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 11 Dec 2024 12:10:13 +0000 Subject: [PATCH 1/3] test-capability: CAP_LINUX_IMMUTABLE is not available in unprivileged containers have ambient caps: yes Capabilities:cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep Failed to drop auxiliary groups list: Operation not permitted Failed to change group ID: Operation not permitted Capabilities:cap_dac_override,cap_net_raw=ep Capabilities:cap_dac_override=ep Successfully forked off '(getambient)' as PID 12505. Skipping PR_SET_MM, as we don't have privileges. Ambient capability cap_linux_immutable requested but missing from bounding set, suppressing automatically. Assertion 'x < 0 || FLAGS_SET(c, UINT64_C(1) << CAP_LINUX_IMMUTABLE)' failed at src/test/test-capability.c:273, function test_capability_get_ambient(). Aborting. (getambient) terminated by signal ABRT. src/test/test-capability.c:258: Assertion failed: expected "r" to succeed, but got error: Protocol error Partially fixes #35552 --- src/test/test-capability.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/test-capability.c b/src/test/test-capability.c index 51bd806348..127f5e3d87 100644 --- a/src/test/test-capability.c +++ b/src/test/test-capability.c @@ -254,6 +254,13 @@ static void test_capability_get_ambient(void) { ASSERT_OK(capability_get_ambient(&c)); + r = prctl(PR_CAPBSET_READ, CAP_MKNOD); + if (r <= 0) + return (void) log_tests_skipped("Lacking CAP_MKNOD, skipping getambient test."); + r = prctl(PR_CAPBSET_READ, CAP_LINUX_IMMUTABLE); + if (r <= 0) + return (void) log_tests_skipped("Lacking CAP_LINUX_IMMUTABLE, skipping getambient test."); + r = safe_fork("(getambient)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL); ASSERT_OK(r); From 630a2e7ee195ca96e102acac8df67a278a879124 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 11 Dec 2024 12:01:18 +0000 Subject: [PATCH 2/3] test-fd-util: skip test when lacking privileges to create a new namespace To reproduce, as an unprivileged user start a docker container and build and run the unit tests inside it: $ docker run --rm -ti debian:bookworm bash ... /* test_close_all_fds */ Successfully forked off '(caf-plain)' as PID 10496. Skipping PR_SET_MM, as we don't have privileges. (caf-plain) succeeded. Failed to fork off '(caf-noproc)': Operation not permitted Assertion 'r >= 0' failed at src/test/test-fd-util.c:392, function test_close_all_fds(). Aborting. Partially fixes #35552 --- src/test/test-fd-util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 20cf7b7627..5817d92725 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -389,6 +389,8 @@ TEST(close_all_fds) { test_close_all_fds_inner(); _exit(EXIT_SUCCESS); } + if (ERRNO_IS_NEG_PRIVILEGE(r)) + return (void) log_tests_skipped("Lacking privileges for test in namespace with /proc/ overmounted"); assert_se(r >= 0); if (!is_seccomp_available()) From 3b32d333e88f2a66651d58e32e01599fa84c3d19 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 11 Dec 2024 13:40:10 +0000 Subject: [PATCH 3/3] test-fd-util: compare FDs to /bin/sh instead of /dev/null /dev/null is a character device, so same_fd() in the fallback path that compares fstat will fail, as that bails out if the fd refers to a char device. This happens on kernels without F_DUPFD_QUERY and without kcmp. /* test_same_fd */ Assertion 'same_fd(d, e) > 0' failed at src/test/test-fd-util.c:111, function test_same_fd(). Aborting. Fixes #35552 --- src/test/test-fd-util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 5817d92725..a359efa052 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -76,9 +76,9 @@ TEST(same_fd) { assert_se(pipe2(p, O_CLOEXEC) >= 0); assert_se((a = fcntl(p[0], F_DUPFD, 3)) >= 0); - assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0); + assert_se((b = open("/bin/sh", O_RDONLY|O_CLOEXEC)) >= 0); assert_se((c = fcntl(a, F_DUPFD, 3)) >= 0); - assert_se((d = open("/dev/null", O_RDONLY|O_CLOEXEC|O_PATH)) >= 0); /* O_PATH changes error returns in F_DUPFD_QUERY, let's test explicitly */ + assert_se((d = open("/bin/sh", O_RDONLY|O_CLOEXEC|O_PATH)) >= 0); /* O_PATH changes error returns in F_DUPFD_QUERY, let's test explicitly */ assert_se((e = fcntl(d, F_DUPFD, 3)) >= 0); assert_se(same_fd(p[0], p[0]) > 0);