From 07d85b4123184c33a2321e05700ff41bb819f99d Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 3 Oct 2019 15:35:51 +0200 Subject: [PATCH] linux: Keep MS_RDONLY when remounting bind mount of a read-only source On Silverblue, the host's /usr is mounted read-only: $ findmnt -o TARGET,OPTIONS,PROPAGATION /usr TARGET OPTIONS PROPAGATION /usr ro,relatime,seclabel shared On such a system, this throws an EPERM when using crun as the OCI runtime: $ podman run \ --rm \ --volume /usr:/run/host/usr:ro \ registry.fedoraproject.org/fedora:31 \ /bin/true Error: remount '... merged/run/host/usr': Operation not permitted: OCI runtime permission denied error The underlying system calls are: mount("/usr", "... merged/run/host/usr", 0x55d5dffb0bc0, MS_NOSUID|MS_NODEV|MS_BIND|MS_REC|MS_SLAVE, 0x55d5dffaeef0) = 0 mount("/usr", "... merged/run/host/usr", 0x55d5dffb0bc0, MS_NOSUID|MS_NODEV|MS_REMOUNT|MS_BIND|MS_REC|MS_SLAVE, NULL) = -1 EPERM (Operation not permitted) Compare that to the system calls generated by runc when used as the runtime with the same Podman invocation: mount("/usr", "... merged/run/host/usr", 0xc000170275, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_BIND|MS_REC, NULL) = 0 mount("", "... merged/run/host/usr", 0xc00017027b, MS_REC|MS_SLAVE, NULL) = 0 mount("/usr", "... merged/run/host/usr", 0xc000170285, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_REMOUNT|MS_BIND|MS_REC, NULL) = 0 What's happening here is that when crun tries to remount the newly created bind mount to apply the rest of the flags unrelated to mount propagation, it doesn't have the MS_RDONLY flag. This isn't allowed because the source on the host (ie., /usr) is mounted read-only. While it's true that the MS_RDONLY flag is ignored in the first invocation of mount(2) that creates the mount-point, there's also no harm in mentioning it because it will be silently ignored. Therefore, it's easier to just keep the flags as they are instead of trying to track which subset of flags are used by each mount(2) invocation. Fixes: f658f17285ba5e87 ("linux: remount to honor flags like ...") --- src/libcrun/linux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcrun/linux.c b/src/libcrun/linux.c index bf6ed25cde..e961dc0341 100644 --- a/src/libcrun/linux.c +++ b/src/libcrun/linux.c @@ -297,9 +297,10 @@ do_mount (libcrun_container_t *container, if ((fstype && fstype[0]) || (mountflags & MS_BIND)) { - unsigned long flags = mountflags & ~MS_RDONLY; + unsigned long flags = mountflags; if ((mountflags & MS_BIND) == 0) flags &= ~ALL_PROPAGATIONS; + ret = mount (source, target, fstype, flags, data); if (UNLIKELY (ret < 0)) {