From: Lennart Poettering Date: Wed, 24 Mar 2021 12:44:56 +0000 (+0100) Subject: test: add test for bind_remount_recursive() X-Git-Tag: v249-rc1~502^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=10cdbb8372238337e0789fc4fc40949f55caddb6;p=thirdparty%2Fsystemd.git test: add test for bind_remount_recursive() --- diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c index 41df5588d08..29f462bfab9 100644 --- a/src/test/test-mount-util.c +++ b/src/test/test-mount-util.c @@ -1,11 +1,20 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" #include "mount-util.h" +#include "namespace-util.h" +#include "path-util.h" +#include "process-util.h" +#include "rm-rf.h" #include "string-util.h" +#include "strv.h" #include "tests.h" +#include "tmpfile-util.h" static void test_mount_option_mangle(void) { char *opts = NULL; @@ -61,10 +70,66 @@ static void test_mount_option_mangle(void) { assert_se(mount_option_mangle("rw,relatime,fmask=0022,dmask=0022,\"hogehoge", MS_RDONLY, &f, &opts) < 0); } +static void test_bind_remount_recursive(void) { + _cleanup_(rm_rf_physical_and_freep) char *tmp = NULL; + _cleanup_free_ char *subdir = NULL; + const char *p; + + if (geteuid() != 0) { + (void) log_tests_skipped("not running as root"); + return; + } + + assert_se(mkdtemp_malloc("/tmp/XXXXXX", &tmp) >= 0); + subdir = path_join(tmp, "subdir"); + assert_se(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) { + 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); + assert_se(!FLAGS_SET(svfs.f_flag, ST_RDONLY)); + + /* Make the subdir a bind mount */ + assert_se(mount_nofollow(subdir, subdir, NULL, MS_BIND|MS_REC, NULL) >= 0); + + /* Ensure it's still writable */ + assert_se(statvfs(subdir, &svfs) >= 0); + assert_se(!FLAGS_SET(svfs.f_flag, ST_RDONLY)); + + /* Now mark the path we currently run for read-only */ + assert_se(bind_remount_recursive(p, MS_RDONLY, MS_RDONLY, STRV_MAKE("/sys/kernel")) >= 0); + + /* Ensure that this worked on the top-level */ + assert_se(statvfs(p, &svfs) >= 0); + assert_se(FLAGS_SET(svfs.f_flag, ST_RDONLY)); + + /* And ensure this had an effect on the subdir exactly if we are talking about a path above the subdir */ + assert_se(statvfs(subdir, &svfs) >= 0); + assert_se(FLAGS_SET(svfs.f_flag, ST_RDONLY) == !!path_startswith(subdir, p)); + + _exit(EXIT_SUCCESS); + } + + assert_se(wait_for_terminate_and_check("test-remount-rec", pid, WAIT_LOG) == EXIT_SUCCESS); + } +} + int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); test_mount_option_mangle(); + test_bind_remount_recursive(); return 0; }