From: Lennart Poettering Date: Sun, 2 Feb 2020 17:56:12 +0000 (+0100) Subject: namespace-util: introduce helper for combining unshare() + MS_SLAVE remount X-Git-Tag: v246-rc1~15^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e2ec9c4d3abf49e95565574214f8979d819e3f48;p=thirdparty%2Fsystemd.git namespace-util: introduce helper for combining unshare() + MS_SLAVE remount We have multiple places we do these two non-trivial operations together, let's introduce a unified helper for doing both at once. --- diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c index b0168ae227c..b34c532604a 100644 --- a/src/basic/namespace-util.c +++ b/src/basic/namespace-util.c @@ -2,6 +2,7 @@ #include #include +#include #include "fd-util.h" #include "missing_fs.h" @@ -169,3 +170,16 @@ int fd_is_network_ns(int fd) { return r == CLONE_NEWNET; } + +int detach_mount_namespace(void) { + + /* Detaches the mount namespace, disabling propagation from our namespace to the host */ + + if (unshare(CLONE_NEWNS) < 0) + return -errno; + + if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) + return -errno; + + return 0; +} diff --git a/src/basic/namespace-util.h b/src/basic/namespace-util.h index 8c17ce91b21..99d9b977edf 100644 --- a/src/basic/namespace-util.h +++ b/src/basic/namespace-util.h @@ -7,3 +7,5 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int * int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd); int fd_is_network_ns(int fd); + +int detach_mount_namespace(void); diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 284b77c1fcc..f76b82a8a45 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -223,11 +223,9 @@ int machine_id_commit(const char *root) { return log_error_errno(r, "Can't fetch current mount namespace: %m"); /* Switch to a new mount namespace, isolate ourself and unmount etc_machine_id in our new namespace */ - if (unshare(CLONE_NEWNS) < 0) - return log_error_errno(errno, "Failed to enter new namespace: %m"); - - if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) - return log_error_errno(errno, "Couldn't make-rslave / mountpoint in our private namespace: %m"); + r = detach_mount_namespace(); + if (r < 0) + return log_error_errno(r, "Failed to set up new mount namespace: %m"); if (umount(etc_machine_id) < 0) return log_error_errno(errno, "Failed to unmount transient %s file in our private namespace: %m", etc_machine_id); diff --git a/src/shared/tests.c b/src/shared/tests.c index ecf8e8f6237..ff662ecfe0c 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -21,6 +21,7 @@ #include "env-util.h" #include "fs-util.h" #include "log.h" +#include "namespace-util.h" #include "path-util.h" #include "random-util.h" #include "strv.h" @@ -137,10 +138,7 @@ bool have_namespaces(void) { if (pid == 0) { /* child */ - if (unshare(CLONE_NEWNS) < 0) - _exit(EXIT_FAILURE); - - if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) + if (detach_mount_namespace() < 0) _exit(EXIT_FAILURE); _exit(EXIT_SUCCESS); diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 208e7a0e96a..c0b215dadc4 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -17,6 +17,7 @@ #include "log.h" #include "main-func.h" #include "mkdir.h" +#include "namespace-util.h" #include "selinux-util.h" #include "signal-util.h" #include "string-util.h" @@ -36,15 +37,13 @@ static int fake_filesystems(void) { { "test/run", "/etc/udev/rules.d", "Failed to mount empty /etc/udev/rules.d", true }, { "test/run", UDEVLIBEXECDIR "/rules.d", "Failed to mount empty " UDEVLIBEXECDIR "/rules.d", true }, }; - unsigned i; - - if (unshare(CLONE_NEWNS) < 0) - return log_error_errno(errno, "Failed to call unshare(): %m"); + int r; - if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) - return log_error_errno(errno, "Failed to mount / as private: %m"); + r = detach_mount_namespace(); + if (r < 0) + return log_error_errno(r, "Failed to detach mount namespace: %m"); - for (i = 0; i < ELEMENTSOF(fakefss); i++) + for (size_t i = 0; i < ELEMENTSOF(fakefss); i++) if (mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL) < 0) { log_full_errno(fakefss[i].ignore_mount_error ? LOG_DEBUG : LOG_ERR, errno, "%s: %m", fakefss[i].error); if (!fakefss[i].ignore_mount_error)