]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf: improve read-only /sys with read-write /sys/devices/virtual/net
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 30 Jun 2021 11:22:15 +0000 (13:22 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 30 Jun 2021 11:22:15 +0000 (13:22 +0200)
Some tools require /sys/devices/virtual/net to be read-write. At the
same time we want all other parts of /sys to be read-only. To do this we
created a layout where we hade a read-only instance of sysfs mounted on
top of a read-write instance of sysfs:

`-/sys                                  sysfs                                                        sysfs      rw,nosuid,nodev,noexec,relatime
  `-/sys                                sysfs                                                        sysfs      ro,nosuid,nodev,noexec,relatime
    |-/sys/devices/virtual/net          sysfs                                                        sysfs      rw,relatime
    | `-/sys/devices/virtual/net        sysfs[/devices/virtual/net]                                  sysfs      rw,nosuid,nodev,noexec,relatime

This causes issues for systemd services that create a separate mount
namespace as they get confused to what mount options need to be
respected.

Simplify our mounting logic so we end up with a single read-only mount
of sysfs on /sys and a read-write bind-mount of /sys/devices/virtual/net:

├─/sys                                sysfs                                                                                  sysfs         ro,nosuid,nodev,noexec,relatime
│ ├─/sys/devices/virtual/net          sysfs[/devices/virtual/net]                                                            sysfs         rw,nosuid,nodev,noexec,relatime

Link: systemd/systemd#20032
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c

index 95ce867eef56e16e3081422bb3d7331a12c3c1f6..d691a8b041668a65561e134b417241fa32de5c7f 100644 (file)
@@ -699,7 +699,7 @@ static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
                 */
                { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "proc",                                           "%r/proc",                    "proc",  MS_NODEV|MS_NOEXEC|MS_NOSUID,                    NULL, false },
                /* proc/tty is used as a temporary placeholder for proc/sys/net which we'll move back in a few steps */
-               { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/sys/net",                                "%r/proc/tty",                NULL,    MS_BIND,                                         NULL, true  },
+               { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/sys/net",                                "%r/proc/tty",                NULL,    MS_BIND,                                         NULL, true, },
                { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/sys",                                    "%r/proc/sys",                NULL,    MS_BIND,                                         NULL, false },
                { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, NULL,                                             "%r/proc/sys",                NULL,    MS_REMOUNT|MS_BIND|MS_RDONLY,                    NULL, false },
                { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED, "%r/proc/tty",                                    "%r/proc/sys/net",            NULL,    MS_MOVE,                                         NULL, true  },
@@ -708,12 +708,9 @@ static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
                { LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW,    "proc",                                           "%r/proc",                    "proc",  MS_NODEV|MS_NOEXEC|MS_NOSUID,                    NULL, false },
                { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_RW,     "sysfs",                                          "%r/sys",                     "sysfs", 0,                                               NULL, false },
                { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_RO,     "sysfs",                                          "%r/sys",                     "sysfs", MS_RDONLY,                                       NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "sysfs",                                          "%r/sys",                     "sysfs", MS_NODEV|MS_NOEXEC|MS_NOSUID,                    NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "%r/sys",                                         "%r/sys",                     NULL,    MS_BIND,                                         NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  NULL,                                             "%r/sys",                     NULL,    MS_REMOUNT|MS_BIND|MS_RDONLY,                    NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "sysfs",                                          "%r/sys/devices/virtual/net", "sysfs", 0,                                               NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "%r/sys/devices/virtual/net/devices/virtual/net", "%r/sys/devices/virtual/net", NULL,    MS_BIND,                                         NULL, false },
-               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  NULL,                                             "%r/sys/devices/virtual/net", NULL,    MS_REMOUNT|MS_BIND|MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL, false },
+               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "sysfs",                                          "%r/sys",                     "sysfs", MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC,          NULL, false },
+               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  "%r/sys/devices/virtual/net",                     "%r/sys/devices/virtual/net",  NULL,   MS_BIND,                                         NULL, false },
+               { LXC_AUTO_SYS_MASK,  LXC_AUTO_SYS_MIXED,  NULL,                                             "%r/sys/devices/virtual/net",  NULL,   MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_NOEXEC,         NULL, false },
                { 0,                  0,                   NULL,                                             NULL,                         NULL,    0,                                               NULL, false }
        };
        struct lxc_conf *conf = handler->conf;
@@ -769,7 +766,7 @@ static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
         has_cap_net_admin = lxc_wants_cap(CAP_NET_ADMIN, conf);
         for (i = 0; default_mounts[i].match_mask; i++) {
                __do_free char *destination = NULL, *source = NULL;
-               unsigned long mflags;
+               unsigned long mflags = default_mounts[i].flags;
 
                if ((flags & default_mounts[i].match_mask) != default_mounts[i].match_flag)
                        continue;
@@ -794,10 +791,10 @@ static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
                if (!destination)
                        return syserror_set(-ENOMEM, "Failed to create target path");
 
-               mflags = add_required_remount_flags(source, destination,
-                                                   default_mounts[i].flags);
-               ret = safe_mount(source, destination, default_mounts[i].fstype,
-                                mflags, default_mounts[i].options,
+               ret = safe_mount(source, destination,
+                                default_mounts[i].fstype,
+                                mflags,
+                                default_mounts[i].options,
                                 rootfs->path ? rootfs->mount : NULL);
                if (ret < 0) {
                        if (errno != ENOENT)
@@ -806,7 +803,11 @@ static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
                        INFO("Mount source or target for \"%s\" on \"%s\" does not exist. Skipping", source, destination);
                        continue;
                }
-               TRACE("Mounted automount \"%s\" on \"%s\" with flags %lu", source, destination, mflags);
+
+               if (mflags & MS_REMOUNT)
+                       TRACE("Remounted automount \"%s\" on \"%s\" %s with flags %lu", source, destination, (mflags & MS_RDONLY) ? "read-only" : "read-write", mflags);
+               else
+                       TRACE("Mounted automount \"%s\" on \"%s\" %s with flags %lu", source, destination, (mflags & MS_RDONLY) ? "read-only" : "read-write", mflags);
        }
 
        if (flags & LXC_AUTO_CGROUP_MASK) {