Merge pull request #12015 from keszybz/fix-tests-in-rawhide
Fix compilation and tests in Fedora rawhide
This commit is contained in:
@@ -74,7 +74,9 @@ static int open_sockets(int *epoll_fd, bool accept) {
|
||||
except[fd] = fd;
|
||||
|
||||
log_close();
|
||||
close_all_fds(except, 3 + n);
|
||||
r = close_all_fds(except, 3 + n);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to close all file descriptors: %m");
|
||||
}
|
||||
|
||||
/** Note: we leak some fd's on error here. I doesn't matter
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "util.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
/* The maximum number of iterations in the loop to close descriptors in the fallback case
|
||||
* when /proc/self/fd/ is inaccessible. */
|
||||
#define MAX_FD_LOOP_LIMIT (1024*1024)
|
||||
|
||||
int close_nointr(int fd) {
|
||||
assert(fd >= 0);
|
||||
|
||||
@@ -228,6 +232,13 @@ int close_all_fds(const int except[], size_t n_except) {
|
||||
if (max_fd < 0)
|
||||
return max_fd;
|
||||
|
||||
/* Refuse to do the loop over more too many elements. It's better to fail immediately than to
|
||||
* spin the CPU for a long time. */
|
||||
if (max_fd > MAX_FD_LOOP_LIMIT)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.",
|
||||
max_fd);
|
||||
|
||||
for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
|
||||
int q;
|
||||
|
||||
|
||||
@@ -1001,7 +1001,7 @@ _noreturn_ void freeze(void) {
|
||||
log_close();
|
||||
|
||||
/* Make sure nobody waits for us on a socket anymore */
|
||||
close_all_fds(NULL, 0);
|
||||
(void) close_all_fds(NULL, 0);
|
||||
|
||||
sync();
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
|
||||
if (rearrange_stdio(-1, pipe_fds[1], -1) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
close_all_fds(NULL, 0);
|
||||
(void) close_all_fds(NULL, 0);
|
||||
|
||||
(void) rlimit_nofile_safe();
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ int stub_pid1(sd_id128_t uuid) {
|
||||
reset_all_signal_handlers();
|
||||
|
||||
log_close();
|
||||
close_all_fds(NULL, 0);
|
||||
(void) close_all_fds(NULL, 0);
|
||||
log_open();
|
||||
|
||||
/* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
|
||||
|
||||
@@ -422,7 +422,7 @@ static int find_sections(
|
||||
n = pread(fd, k, size, offset);
|
||||
if (n < 0)
|
||||
return log_error_errno(errno, "Failed to read section payload: %m");
|
||||
if (n != size)
|
||||
if ((size_t) n != size)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short read while reading section payload, refusing:");
|
||||
|
||||
/* Allow one trailing NUL byte, but nothing more. */
|
||||
|
||||
@@ -1502,14 +1502,9 @@ static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp,
|
||||
assert_cc(SCMP_SYS(shmget) > 0);
|
||||
assert_cc(SCMP_SYS(shmat) > 0);
|
||||
assert_cc(SCMP_SYS(shmdt) > 0);
|
||||
#elif defined(__i386__) || defined(__powerpc64__)
|
||||
assert_cc(SCMP_SYS(shmget) < 0);
|
||||
assert_cc(SCMP_SYS(shmat) < 0);
|
||||
assert_cc(SCMP_SYS(shmdt) < 0);
|
||||
#endif
|
||||
|
||||
int seccomp_memory_deny_write_execute(void) {
|
||||
|
||||
uint32_t arch;
|
||||
int r;
|
||||
|
||||
@@ -1524,6 +1519,7 @@ int seccomp_memory_deny_write_execute(void) {
|
||||
case SCMP_ARCH_X86:
|
||||
filter_syscall = SCMP_SYS(mmap2);
|
||||
block_syscall = SCMP_SYS(mmap);
|
||||
shmat_syscall = SCMP_SYS(shmat);
|
||||
break;
|
||||
|
||||
case SCMP_ARCH_PPC:
|
||||
@@ -1590,7 +1586,7 @@ int seccomp_memory_deny_write_execute(void) {
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (shmat_syscall != 0) {
|
||||
if (shmat_syscall > 0) {
|
||||
r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
|
||||
1,
|
||||
SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
|
||||
|
||||
+62
-50
@@ -327,7 +327,7 @@ static void test_exec_inaccessiblepaths(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
test(m, "exec-inaccessiblepaths-proc.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
test(m, "exec-inaccessiblepaths-sys.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
|
||||
if (path_is_read_only_fs("/") > 0) {
|
||||
log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
|
||||
@@ -696,8 +696,15 @@ static void test_exec_standardoutput_append(Manager *m) {
|
||||
test(m, "exec-standardoutput-append.service", 0, CLD_EXITED);
|
||||
}
|
||||
|
||||
static int run_tests(UnitFileScope scope, const test_function_t *tests) {
|
||||
const test_function_t *test = NULL;
|
||||
typedef struct test_entry {
|
||||
test_function_t f;
|
||||
const char *name;
|
||||
} test_entry;
|
||||
|
||||
#define entry(x) {x, #x}
|
||||
|
||||
static int run_tests(UnitFileScope scope, const test_entry tests[], char **patterns) {
|
||||
const test_entry *test = NULL;
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -709,57 +716,62 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) {
|
||||
assert_se(r >= 0);
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
|
||||
for (test = tests; test && *test; test++)
|
||||
(*test)(m);
|
||||
for (test = tests; test && test->f; test++)
|
||||
if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||||
test->f(m);
|
||||
else
|
||||
log_info("Skipping %s because it does not match any pattern.", test->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||||
_cleanup_free_ char *test_execute_path = NULL;
|
||||
static const test_function_t user_tests[] = {
|
||||
test_exec_basic,
|
||||
test_exec_ambientcapabilities,
|
||||
test_exec_bindpaths,
|
||||
test_exec_capabilityboundingset,
|
||||
test_exec_cpuaffinity,
|
||||
test_exec_environment,
|
||||
test_exec_environmentfile,
|
||||
test_exec_group,
|
||||
test_exec_ignoresigpipe,
|
||||
test_exec_inaccessiblepaths,
|
||||
test_exec_ioschedulingclass,
|
||||
test_exec_oomscoreadjust,
|
||||
test_exec_passenvironment,
|
||||
test_exec_personality,
|
||||
test_exec_privatedevices,
|
||||
test_exec_privatenetwork,
|
||||
test_exec_privatetmp,
|
||||
test_exec_protecthome,
|
||||
test_exec_protectkernelmodules,
|
||||
test_exec_readonlypaths,
|
||||
test_exec_readwritepaths,
|
||||
test_exec_restrictnamespaces,
|
||||
test_exec_runtimedirectory,
|
||||
test_exec_standardinput,
|
||||
test_exec_standardoutput,
|
||||
test_exec_standardoutput_append,
|
||||
test_exec_supplementarygroups,
|
||||
test_exec_systemcallerrornumber,
|
||||
test_exec_systemcallfilter,
|
||||
test_exec_temporaryfilesystem,
|
||||
test_exec_umask,
|
||||
test_exec_unsetenvironment,
|
||||
test_exec_user,
|
||||
test_exec_workingdirectory,
|
||||
NULL,
|
||||
|
||||
static const test_entry user_tests[] = {
|
||||
entry(test_exec_basic),
|
||||
entry(test_exec_ambientcapabilities),
|
||||
entry(test_exec_bindpaths),
|
||||
entry(test_exec_capabilityboundingset),
|
||||
entry(test_exec_cpuaffinity),
|
||||
entry(test_exec_environment),
|
||||
entry(test_exec_environmentfile),
|
||||
entry(test_exec_group),
|
||||
entry(test_exec_ignoresigpipe),
|
||||
entry(test_exec_inaccessiblepaths),
|
||||
entry(test_exec_ioschedulingclass),
|
||||
entry(test_exec_oomscoreadjust),
|
||||
entry(test_exec_passenvironment),
|
||||
entry(test_exec_personality),
|
||||
entry(test_exec_privatedevices),
|
||||
entry(test_exec_privatenetwork),
|
||||
entry(test_exec_privatetmp),
|
||||
entry(test_exec_protecthome),
|
||||
entry(test_exec_protectkernelmodules),
|
||||
entry(test_exec_readonlypaths),
|
||||
entry(test_exec_readwritepaths),
|
||||
entry(test_exec_restrictnamespaces),
|
||||
entry(test_exec_runtimedirectory),
|
||||
entry(test_exec_standardinput),
|
||||
entry(test_exec_standardoutput),
|
||||
entry(test_exec_standardoutput_append),
|
||||
entry(test_exec_supplementarygroups),
|
||||
entry(test_exec_systemcallerrornumber),
|
||||
entry(test_exec_systemcallfilter),
|
||||
entry(test_exec_temporaryfilesystem),
|
||||
entry(test_exec_umask),
|
||||
entry(test_exec_unsetenvironment),
|
||||
entry(test_exec_user),
|
||||
entry(test_exec_workingdirectory),
|
||||
{},
|
||||
};
|
||||
static const test_function_t system_tests[] = {
|
||||
test_exec_dynamicuser,
|
||||
test_exec_specifier,
|
||||
test_exec_systemcallfilter_system,
|
||||
NULL,
|
||||
static const test_entry system_tests[] = {
|
||||
entry(test_exec_dynamicuser),
|
||||
entry(test_exec_specifier),
|
||||
entry(test_exec_systemcallfilter_system),
|
||||
{},
|
||||
};
|
||||
int r;
|
||||
|
||||
@@ -801,11 +813,11 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(unsetenv("VAR2") == 0);
|
||||
assert_se(unsetenv("VAR3") == 0);
|
||||
|
||||
r = run_tests(UNIT_FILE_USER, user_tests);
|
||||
r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = run_tests(UNIT_FILE_SYSTEM, system_tests);
|
||||
r = run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
@@ -827,11 +839,11 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
can_unshare = false;
|
||||
|
||||
r = run_tests(UNIT_FILE_USER, user_tests);
|
||||
r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
return run_tests(UNIT_FILE_SYSTEM, system_tests);
|
||||
return run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
+15
-3
@@ -507,9 +507,18 @@ static void test_memory_deny_write_execute_mmap(void) {
|
||||
static void test_memory_deny_write_execute_shmat(void) {
|
||||
int shmid;
|
||||
pid_t pid;
|
||||
uint32_t arch;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
|
||||
log_debug("arch %s: SCMP_SYS(mmap) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap));
|
||||
log_debug("arch %s: SCMP_SYS(mmap2) = %d", seccomp_arch_to_string(arch), SCMP_SYS(mmap2));
|
||||
log_debug("arch %s: SCMP_SYS(shmget) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmget));
|
||||
log_debug("arch %s: SCMP_SYS(shmat) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmat));
|
||||
log_debug("arch %s: SCMP_SYS(shmdt) = %d", seccomp_arch_to_string(arch), SCMP_SYS(shmdt));
|
||||
}
|
||||
|
||||
if (!is_seccomp_available()) {
|
||||
log_notice("Seccomp not available, skipping %s", __func__);
|
||||
return;
|
||||
@@ -539,15 +548,18 @@ static void test_memory_deny_write_execute_shmat(void) {
|
||||
assert_se(seccomp_memory_deny_write_execute() >= 0);
|
||||
|
||||
p = shmat(shmid, NULL, SHM_EXEC);
|
||||
log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(SHM_EXEC): %m");
|
||||
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
|
||||
assert_se(p == MAP_FAILED);
|
||||
assert_se(errno == EPERM);
|
||||
#else /* __i386__, __powerpc64__, and "unknown" architectures */
|
||||
assert_se(p != MAP_FAILED);
|
||||
assert_se(shmdt(p) == 0);
|
||||
#endif
|
||||
/* Depending on kernel, libseccomp, and glibc versions, other architectures
|
||||
* might fail or not. Let's not assert success. */
|
||||
if (p != MAP_FAILED)
|
||||
assert_se(shmdt(p) == 0);
|
||||
|
||||
p = shmat(shmid, NULL, 0);
|
||||
log_debug_errno(p == MAP_FAILED ? errno : 0, "shmat(0): %m");
|
||||
assert_se(p != MAP_FAILED);
|
||||
assert_se(shmdt(p) == 0);
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ test_data_files = '''
|
||||
test-execute/exec-ignoresigpipe-no.service
|
||||
test-execute/exec-ignoresigpipe-yes.service
|
||||
test-execute/exec-inaccessiblepaths-mount-propagation.service
|
||||
test-execute/exec-inaccessiblepaths-proc.service
|
||||
test-execute/exec-inaccessiblepaths-sys.service
|
||||
test-execute/exec-ioschedulingclass-best-effort.service
|
||||
test-execute/exec-ioschedulingclass-idle.service
|
||||
test-execute/exec-ioschedulingclass-none.service
|
||||
|
||||
+2
-2
@@ -2,6 +2,6 @@
|
||||
Description=Test to make sure that mount namespace setup works properly with the 'InaccessiblePaths=/proc' option
|
||||
|
||||
[Service]
|
||||
InaccessiblePaths=/proc
|
||||
ExecStart=/bin/sh -x -c 'test "$$(stat -c %%a /proc)" = "0"'
|
||||
InaccessiblePaths=/sys
|
||||
ExecStart=/bin/sh -x -c 'test "$$(stat -c %%a /sys)" = "0"'
|
||||
Type=oneshot
|
||||
Reference in New Issue
Block a user