]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount-util: Add a helper for remounting a bind mount
authorKrzesimir Nowak <knowak@microsoft.com>
Tue, 23 Jan 2024 09:44:23 +0000 (10:44 +0100)
committerKrzesimir Nowak <knowak@microsoft.com>
Thu, 22 Feb 2024 18:06:22 +0000 (19:06 +0100)
src/shared/mount-util.c
src/shared/mount-util.h
src/test/test-mount-util.c

index bff1bf9f49c1ed2b57a32900305af703a974498a..77b18c375c240e5a8d9d494445d80a5640a78d8f 100644 (file)
@@ -453,6 +453,16 @@ int bind_remount_one_with_mountinfo(
         return 0;
 }
 
+int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask) {
+        _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+        proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+        if (!proc_self_mountinfo)
+                return log_debug_errno(errno, "Failed to open /proc/self/mountinfo: %m");
+
+        return bind_remount_one_with_mountinfo(path, new_flags, flags_mask, proc_self_mountinfo);
+}
+
 static int mount_switch_root_pivot(int fd_newroot, const char *path) {
         assert(fd_newroot >= 0);
         assert(path);
index 2f9f394ab0edd8e107c482c47827322f0baa3fde..26d96b27b7feb7fb3467714921195116845e0fe5 100644 (file)
@@ -26,6 +26,7 @@ static inline int bind_remount_recursive(const char *prefix, unsigned long new_f
 }
 
 int bind_remount_one_with_mountinfo(const char *path, unsigned long new_flags, unsigned long flags_mask, FILE *proc_self_mountinfo);
+int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask);
 
 int mount_switch_root_full(const char *path, unsigned long mount_propagation_flag, bool force_ms_move);
 static inline int mount_switch_root(const char *path, unsigned long mount_propagation_flag) {
index 3e22ac67fc85b4cd97c4d62fc65f3719b5564159..77fce983b912af6e1504c9a6720a27cfaa147d4a 100644 (file)
@@ -213,6 +213,25 @@ TEST(bind_remount_one) {
                 _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_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);
+                assert_se(bind_remount_one("/proc/self", MS_RDONLY, MS_RDONLY) == -EINVAL);
+                assert_se(bind_remount_one("/", MS_RDONLY, MS_RDONLY) >= 0);
+
+                _exit(EXIT_SUCCESS);
+        }
+
         assert_se(wait_for_terminate_and_check("test-remount-one", pid, WAIT_LOG) == EXIT_SUCCESS);
 }