#include "tests.h"
#include "tmpfile-util.h"
+#define FORK_COMMON_FLAGS \
+ (FORK_CLOSE_ALL_FDS | \
+ FORK_RESET_SIGNALS | \
+ FORK_DEATHSIG_SIGTERM | \
+ FORK_LOG | \
+ FORK_REOPEN_LOG | \
+ FORK_WAIT | \
+ FORK_NEW_MOUNTNS | \
+ FORK_MOUNTNS_SLAVE)
+
+#define CHECK_PRIV \
+ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \
+ return (void) log_tests_skipped("Not privileged");
+
TEST(mount_option_mangle) {
char *opts = NULL;
unsigned long f;
TEST(bind_remount_recursive) {
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
_cleanup_free_ char *subdir = NULL;
+ int r;
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
- (void) log_tests_skipped("not running privileged");
- return;
- }
+ CHECK_PRIV;
assert_se(mkdtemp_malloc("/tmp/XXXXXX", &tmp) >= 0);
subdir = path_join(tmp, "subdir");
assert_se(mkdir(subdir, 0755) >= 0);
FOREACH_STRING(p, "/usr", "/sys", "/", tmp) {
- pid_t pid;
-
- pid = fork();
- assert_se(pid >= 0);
-
- if (pid == 0) {
+ ASSERT_OK(r = safe_fork("(bind-remount-recursive)", FORK_COMMON_FLAGS, NULL));
+ if (r == 0) { /* child */
struct statvfs svfs;
- /* child */
- assert_se(detach_mount_namespace() >= 0);
/* Check that the subdir is writable (it must be because it's in /tmp) */
assert_se(statvfs(subdir, &svfs) >= 0);
_exit(EXIT_SUCCESS);
}
-
- assert_se(wait_for_terminate_and_check("test-remount-rec", pid, WAIT_LOG) == EXIT_SUCCESS);
}
}
TEST(bind_remount_one) {
- pid_t pid;
-
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
- (void) log_tests_skipped("not running privileged");
- return;
- }
-
- pid = fork();
- assert_se(pid >= 0);
+ int r;
- if (pid == 0) {
- /* child */
+ CHECK_PRIV;
+ ASSERT_OK(r = safe_fork("(remount-one-with-mountinfo)", FORK_COMMON_FLAGS, NULL));
+ if (r == 0) { /* child */
_cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
- assert_se(detach_mount_namespace() >= 0);
-
assert_se(fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo) >= 0);
assert_se(bind_remount_one_with_mountinfo("/run", MS_RDONLY, MS_RDONLY, proc_self_mountinfo) >= 0);
_exit(EXIT_SUCCESS);
}
- assert_se(wait_for_terminate_and_check("test-remount-one-with-mountinfo", pid, WAIT_LOG) == EXIT_SUCCESS);
-
- pid = fork();
- assert_se(pid >= 0);
-
- if (pid == 0) {
- /* child */
-
- assert_se(detach_mount_namespace() >= 0);
-
+ ASSERT_OK(r = safe_fork("(remount-one)", FORK_COMMON_FLAGS, NULL));
+ if (r == 0) { /* child */
assert_se(bind_remount_one("/run", MS_RDONLY, MS_RDONLY) >= 0);
assert_se(bind_remount_one("/run", MS_NOEXEC, MS_RDONLY|MS_NOEXEC) >= 0);
assert_se(bind_remount_one("/proc/idontexist", MS_RDONLY, MS_RDONLY) == -ENOENT);
_exit(EXIT_SUCCESS);
}
-
- assert_se(wait_for_terminate_and_check("test-remount-one", pid, WAIT_LOG) == EXIT_SUCCESS);
}
TEST(make_mount_point_inode) {
_cleanup_free_ char *s = NULL;
int r;
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
- (void) log_tests_skipped("not running privileged");
- return;
- }
+ CHECK_PRIV;
assert_se(mkdtemp_malloc(NULL, &t) >= 0);
};
FOREACH_ELEMENT(i, table) {
- r = safe_fork("(switch-root)",
- FORK_RESET_SIGNALS |
- FORK_CLOSE_ALL_FDS |
- FORK_DEATHSIG_SIGTERM |
- FORK_WAIT |
- FORK_REOPEN_LOG |
- FORK_LOG |
- FORK_NEW_MOUNTNS |
- FORK_MOUNTNS_SLAVE,
- NULL);
- assert_se(r >= 0);
-
+ ASSERT_OK(r = safe_fork("(switch-root)", FORK_COMMON_FLAGS, NULL));
if (r == 0) {
assert_se(make_mount_point(i->path) >= 0);
assert_se(mount_switch_root_full(i->path, /* mount_propagation_flag= */ 0, i->force_ms_move) >= 0);
int r;
- FOREACH_ELEMENT(t, test_table) {
+ CHECK_PRIV;
- r = safe_fork("(umount-rec)",
- FORK_RESET_SIGNALS |
- FORK_CLOSE_ALL_FDS |
- FORK_DEATHSIG_SIGTERM |
- FORK_WAIT |
- FORK_REOPEN_LOG |
- FORK_LOG |
- FORK_NEW_MOUNTNS |
- FORK_MOUNTNS_SLAVE,
- NULL);
-
- if (ERRNO_IS_NEG_PRIVILEGE(r))
- return (void) log_notice("Skipping umount_recursive() test, lacking privileges");
-
- assert_se(r >= 0);
+ FOREACH_ELEMENT(t, test_table) {
+ ASSERT_OK(r = safe_fork("(umount-rec)", FORK_COMMON_FLAGS, NULL));
if (r == 0) { /* child */
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
_cleanup_free_ char *s = NULL;
int r;
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
- (void) log_tests_skipped("not running privileged");
- return;
- }
+ CHECK_PRIV;
assert_se(mkdtemp_malloc(NULL, &t) >= 0);
assert_se(s);
assert_se(mkdir(s, 0700) >= 0);
- r = safe_fork("(make_mount-point)",
- FORK_RESET_SIGNALS |
- FORK_CLOSE_ALL_FDS |
- FORK_DEATHSIG_SIGTERM |
- FORK_WAIT |
- FORK_REOPEN_LOG |
- FORK_LOG |
- FORK_NEW_MOUNTNS |
- FORK_MOUNTNS_SLAVE,
- NULL);
- assert_se(r >= 0);
-
+ ASSERT_OK(r = safe_fork("(make-mount-point)", FORK_COMMON_FLAGS, NULL));
if (r == 0) {
_cleanup_close_ int fd = -EBADF, fd2 = -EBADF;
TEST(bind_mount_submounts) {
_cleanup_(rmdir_and_freep) char *a = NULL, *b = NULL;
- _cleanup_free_ char *x = NULL;
int r;
+ CHECK_PRIV;
+
assert_se(mkdtemp_malloc(NULL, &a) >= 0);
- r = mount_nofollow_verbose(LOG_INFO, "tmpfs", a, "tmpfs", 0, NULL);
- if (ERRNO_IS_NEG_PRIVILEGE(r))
- return (void) log_tests_skipped("Skipping bind_mount_submounts() test, lacking privileges");
+ assert_se(mkdtemp_malloc(NULL, &b) >= 0);
- assert_se(r >= 0);
+ ASSERT_OK(r = safe_fork("(bind-mount-submounts)", FORK_COMMON_FLAGS, NULL));
+ if (r == 0) {
+ char *x;
- assert_se(x = path_join(a, "foo"));
- assert_se(touch(x) >= 0);
- free(x);
+ ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", a, "tmpfs", 0, NULL));
- assert_se(x = path_join(a, "x"));
- assert_se(mkdir(x, 0755) >= 0);
- assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
- free(x);
+ assert_se(x = path_join(a, "foo"));
+ assert_se(touch(x) >= 0);
+ free(x);
- assert_se(x = path_join(a, "x/xx"));
- assert_se(touch(x) >= 0);
- free(x);
+ assert_se(x = path_join(a, "x"));
+ assert_se(mkdir(x, 0755) >= 0);
+ assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
+ free(x);
- assert_se(x = path_join(a, "y"));
- assert_se(mkdir(x, 0755) >= 0);
- assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
- free(x);
+ assert_se(x = path_join(a, "x/xx"));
+ assert_se(touch(x) >= 0);
+ free(x);
- assert_se(x = path_join(a, "y/yy"));
- assert_se(touch(x) >= 0);
- free(x);
+ assert_se(x = path_join(a, "y"));
+ assert_se(mkdir(x, 0755) >= 0);
+ assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", x, "tmpfs", 0, NULL) >= 0);
+ free(x);
- assert_se(mkdtemp_malloc(NULL, &b) >= 0);
- assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", b, "tmpfs", 0, NULL) >= 0);
+ assert_se(x = path_join(a, "y/yy"));
+ assert_se(touch(x) >= 0);
+ free(x);
+
+ assert_se(mount_nofollow_verbose(LOG_INFO, "tmpfs", b, "tmpfs", 0, NULL) >= 0);
+
+ assert_se(x = path_join(b, "x"));
+ assert_se(mkdir(x, 0755) >= 0);
+ free(x);
- assert_se(x = path_join(b, "x"));
- assert_se(mkdir(x, 0755) >= 0);
- free(x);
+ assert_se(x = path_join(b, "y"));
+ assert_se(mkdir(x, 0755) >= 0);
+ free(x);
- assert_se(x = path_join(b, "y"));
- assert_se(mkdir(x, 0755) >= 0);
- free(x);
+ assert_se(bind_mount_submounts(a, b) >= 0);
- assert_se(bind_mount_submounts(a, b) >= 0);
+ assert_se(x = path_join(b, "foo"));
+ assert_se(access(x, F_OK) < 0 && errno == ENOENT);
+ free(x);
- assert_se(x = path_join(b, "foo"));
- assert_se(access(x, F_OK) < 0 && errno == ENOENT);
- free(x);
+ assert_se(x = path_join(b, "x/xx"));
+ assert_se(access(x, F_OK) >= 0);
+ free(x);
- assert_se(x = path_join(b, "x/xx"));
- assert_se(access(x, F_OK) >= 0);
- free(x);
+ assert_se(x = path_join(b, "y/yy"));
+ assert_se(access(x, F_OK) >= 0);
+ free(x);
- assert_se(x = path_join(b, "y/yy"));
- assert_se(access(x, F_OK) >= 0);
- free(x);
+ assert_se(x = path_join(b, "x"));
+ assert_se(path_is_mount_point(x) > 0);
+ free(x);
- assert_se(x = path_join(b, "x"));
- assert_se(path_is_mount_point(x) > 0);
- free(x);
+ assert_se(x = path_join(b, "y"));
+ assert_se(path_is_mount_point(x) > 0);
+ free(x);
- assert_se(x = path_join(b, "y"));
- assert_se(path_is_mount_point(x) > 0);
+ assert_se(umount_recursive(a, 0) >= 0);
+ assert_se(umount_recursive(b, 0) >= 0);
- assert_se(umount_recursive(a, 0) >= 0);
- assert_se(umount_recursive(b, 0) >= 0);
+ _exit(EXIT_SUCCESS);
+ }
}
TEST(path_is_network_fs_harder) {
log_debug("path_is_network_fs_harder_at(root, %s) → %i: %s", q, r, r < 0 ? STRERROR(r) : yes_no(r));
}
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
- (void) log_tests_skipped("not running privileged");
- return;
- }
+ CHECK_PRIV;
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
assert_se(mkdtemp_malloc("/tmp/test-mount-util.path_is_network_fs_harder.XXXXXXX", &t) >= 0);
- r = safe_fork("(make_mount-point)",
- FORK_RESET_SIGNALS |
- FORK_CLOSE_ALL_FDS |
- FORK_DEATHSIG_SIGTERM |
- FORK_WAIT |
- FORK_REOPEN_LOG |
- FORK_LOG |
- FORK_NEW_MOUNTNS |
- FORK_MOUNTNS_SLAVE,
- NULL);
- ASSERT_OK(r);
-
+ ASSERT_OK(r = safe_fork("(path-is-network-fs-harder)", FORK_COMMON_FLAGS, NULL));
if (r == 0) {
ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, NULL));
ASSERT_OK_ZERO(path_is_network_fs_harder(t));
}
TEST(umountat) {
- int r;
+ CHECK_PRIV;
_cleanup_(rm_rf_physical_and_freep) char *p = NULL;
_cleanup_close_ int dfd = mkdtemp_open(NULL, O_CLOEXEC, &p);
_cleanup_free_ char *q = ASSERT_PTR(path_join(p, "foo"));
- r = mount_nofollow_verbose(LOG_ERR, "tmpfs", q, "tmpfs", 0, NULL);
- if (ERRNO_IS_NEG_PRIVILEGE(r))
- return (void) log_tests_skipped("not running privileged");
-
- ASSERT_OK(r);
+ ASSERT_OK(mount_nofollow_verbose(LOG_ERR, "tmpfs", q, "tmpfs", 0, NULL));
ASSERT_OK(umountat_detach_verbose(LOG_ERR, dfd, "foo"));
ASSERT_ERROR(umountat_detach_verbose(LOG_ERR, dfd, "foo"), EINVAL);
}