]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #1619 from iaguis/nspawn-sysfs-netns-3
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Oct 2015 10:22:32 +0000 (12:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 20 Oct 2015 10:22:32 +0000 (12:22 +0200)
nspawn: skip /sys-as-tmpfs if we don't use private-network

src/basic/util.c
src/basic/util.h
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn.c

index a14ed2e4cc431f0b60b20b804a2b4ca7b301999f..3e90456dd3ef73de6221802d7ee1362f2a22e008 100644 (file)
@@ -2500,11 +2500,35 @@ char *getusername_malloc(void) {
         return lookup_uid(getuid());
 }
 
-bool is_temporary_fs(const struct statfs *s) {
+bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
         assert(s);
+        assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
+
+        return F_TYPE_EQUAL(s->f_type, magic_value);
+}
+
+int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
+        struct statfs s;
+
+        if (fstatfs(fd, &s) < 0)
+                return -errno;
+
+        return is_fs_type(&s, magic_value);
+}
+
+int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
+        _cleanup_close_ int fd = -1;
 
-        return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
-               F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
+        fd = open(path, O_RDONLY);
+        if (fd < 0)
+                return -errno;
+
+        return fd_check_fstype(fd, magic_value);
+}
+
+bool is_temporary_fs(const struct statfs *s) {
+    return is_fs_type(s, TMPFS_MAGIC) ||
+           is_fs_type(s, RAMFS_MAGIC);
 }
 
 int fd_is_temporary_fs(int fd) {
index 4b1c5878c52f8d3ef519bb9f13419c8f1a2a634a..ff39eae715e9125536a88185d6ae452cce68d81a 100644 (file)
@@ -365,6 +365,12 @@ char* getusername_malloc(void);
 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
 
+typedef long statfs_f_type_t;
+
+bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_;
+int fd_check_fstype(int fd, statfs_f_type_t magic_value);
+int path_check_fstype(const char *path, statfs_f_type_t magic_value);
+
 bool is_temporary_fs(const struct statfs *s) _pure_;
 int fd_is_temporary_fs(int fd);
 
index 6c8b1d7a2651fcaec73539b6757944a13e446a35..65bcb682428c87cc0567fd404c23993e07611822 100644 (file)
@@ -20,6 +20,7 @@
 ***/
 
 #include <sys/mount.h>
+#include <linux/magic.h>
 
 #include "util.h"
 #include "rm-rf.h"
@@ -218,8 +219,19 @@ static int tmpfs_patch_options(
 
 int mount_sysfs(const char *dest) {
         const char *full, *top, *x;
+        int r;
 
         top = prefix_roota(dest, "/sys");
+        r = path_check_fstype(top, SYSFS_MAGIC);
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine filesystem type of %s: %m", top);
+        /* /sys might already be mounted as sysfs by the outer child in the
+         * !netns case. In this case, it's all good. Don't touch it because we
+         * don't have the right to do so, see https://github.com/systemd/systemd/issues/1555.
+         */
+        if (r > 0)
+                return 0;
+
         full = prefix_roota(top, "/full");
 
         (void) mkdir(full, 0755);
@@ -264,6 +276,7 @@ int mount_sysfs(const char *dest) {
 
 int mount_all(const char *dest,
               bool use_userns, bool in_userns,
+              bool use_netns,
               uid_t uid_shift, uid_t uid_range,
               const char *selinux_apifs_context) {
 
@@ -274,21 +287,23 @@ int mount_all(const char *dest,
                 const char *options;
                 unsigned long flags;
                 bool fatal;
-                bool userns;
+                bool in_userns;
+                bool use_netns;
         } MountPoint;
 
         static const MountPoint mount_table[] = {
-                { "proc",      "/proc",          "proc",   NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,                              true,  true  },
-                { "/proc/sys", "/proc/sys",      NULL,     NULL,        MS_BIND,                                                   true,  true  },   /* Bind mount first */
-                { NULL,        "/proc/sys",      NULL,     NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true,  true  },   /* Then, make it r/o */
-                { "tmpfs",     "/sys",           "tmpfs",  "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV,                              true,  false },
-                { "tmpfs",     "/dev",           "tmpfs",  "mode=755",  MS_NOSUID|MS_STRICTATIME,                                  true,  false },
-                { "tmpfs",     "/dev/shm",       "tmpfs",  "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         true,  false },
-                { "tmpfs",     "/run",           "tmpfs",  "mode=755",  MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         true,  false },
-                { "tmpfs",     "/tmp",           "tmpfs",  "mode=1777", MS_STRICTATIME,                                            true,  false },
+                { "proc",      "/proc",          "proc",   NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,                              true,  true, false  },
+                { "/proc/sys", "/proc/sys",      NULL,     NULL,        MS_BIND,                                                   true,  true, false  },   /* Bind mount first */
+                { NULL,        "/proc/sys",      NULL,     NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true,  true, false  },   /* Then, make it r/o */
+                { "tmpfs",     "/sys",           "tmpfs",  "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV,                              true,  false, true },
+                { "sysfs",     "/sys",           "sysfs",  NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,                    true,  false, false },
+                { "tmpfs",     "/dev",           "tmpfs",  "mode=755",  MS_NOSUID|MS_STRICTATIME,                                  true,  false, false },
+                { "tmpfs",     "/dev/shm",       "tmpfs",  "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         true,  false, false },
+                { "tmpfs",     "/run",           "tmpfs",  "mode=755",  MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         true,  false, false },
+                { "tmpfs",     "/tmp",           "tmpfs",  "mode=1777", MS_STRICTATIME,                                            true,  false, false },
 #ifdef HAVE_SELINUX
-                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL,     MS_BIND,                                                   false, false },  /* Bind mount first */
-                { NULL,              "/sys/fs/selinux", NULL, NULL,     MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, false, false },  /* Then, make it r/o */
+                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL,     MS_BIND,                                                   false, false, false },  /* Bind mount first */
+                { NULL,              "/sys/fs/selinux", NULL, NULL,     MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, false, false, false },  /* Then, make it r/o */
 #endif
         };
 
@@ -299,7 +314,10 @@ int mount_all(const char *dest,
                 _cleanup_free_ char *where = NULL, *options = NULL;
                 const char *o;
 
-                if (in_userns != mount_table[k].userns)
+                if (in_userns != mount_table[k].in_userns)
+                        continue;
+
+                if (!use_netns && mount_table[k].use_netns)
                         continue;
 
                 where = prefix_root(dest, mount_table[k].where);
index 54cab87665dd9c95807f564d26bf9c508e66c640..bdab23bcca2476ffeeeb3d18692df6046a178bb5 100644 (file)
@@ -57,7 +57,7 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
 
 int custom_mount_compare(const void *a, const void *b);
 
-int mount_all(const char *dest, bool use_userns, bool in_userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
+int mount_all(const char *dest, bool use_userns, bool in_userns, bool use_netns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
 int mount_sysfs(const char *dest);
 
 int mount_cgroups(const char *dest, bool unified_requested, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
index ab93f98df41f87816a7c10897be07ee935a68b0f..fca2b72edd40fe7d3803c9406931019f4396bcc3 100644 (file)
@@ -2450,7 +2450,7 @@ static int inner_child(
                 }
         }
 
-        r = mount_all(NULL, arg_userns, true, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+        r = mount_all(NULL, arg_userns, true, arg_uid_shift, arg_private_network, arg_uid_range, arg_selinux_apifs_context);
         if (r < 0)
                 return r;
 
@@ -2705,7 +2705,7 @@ static int outer_child(
                         return log_error_errno(r, "Failed to make tree read-only: %m");
         }
 
-        r = mount_all(directory, arg_userns, false, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+        r = mount_all(directory, arg_userns, false, arg_private_network, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
         if (r < 0)
                 return r;