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.
This commit is contained in:
Lennart Poettering 2020-02-02 18:56:12 +01:00
parent cda667722c
commit e2ec9c4d3a
5 changed files with 27 additions and 16 deletions

View file

@ -2,6 +2,7 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;
int r;
if (unshare(CLONE_NEWNS) < 0)
return log_error_errno(errno, "Failed to call unshare(): %m");
r = detach_mount_namespace();
if (r < 0)
return log_error_errno(r, "Failed to detach mount namespace: %m");
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
return log_error_errno(errno, "Failed to mount / as private: %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)