Fix failure with rw bind mount of a ro fuse#3283
Fix failure with rw bind mount of a ro fuse#3283thaJeztah merged 1 commit intoopencontainers:masterfrom
Conversation
08915b8 to
dd466b3
Compare
dd466b3 to
fe6a902
Compare
fe6a902 to
d7846bc
Compare
tests/integration/mounts.bats
Outdated
| [ "$status" -eq 0 ] | ||
| } | ||
|
|
||
| @test "runc run [rw bind mount of a ro fuse sshfs mount]" { |
There was a problem hiding this comment.
Can we move this into mounts_sshfs.bats, as this has huge extra depenedency?
Or maybe just skip the sshfs test by default and require some env var to opt-in to the sshfs test.
There was a problem hiding this comment.
Done. If sshfs is not installed or not working for some reason, the test is skipped.
| return mount(source, m.Destination, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), "") | ||
| flags := uintptr(m.Flags | unix.MS_REMOUNT) | ||
| err := mount(source, m.Destination, procfd, m.Device, flags, "") | ||
| if err == nil { |
There was a problem hiding this comment.
Can we rather check errors.Is(err, syscall.EPERM)?
There was a problem hiding this comment.
A different kernel might return a different error, and if the original mount is not read-only, we still return that error, and if it is, a retry with added RO flag will most probably return the very same error.
In other words, the error path overhead of a statfs() and (maybe) a mount() is pretty small, and the error returned is most probably the same, so it makes sense to retry on any error.
There was a problem hiding this comment.
In short, it doesn't hurt to retry even if there was an error other than EPERM.
d5bf4e0 to
20e15a2
Compare
As reported in [1], in a case where read-only fuse (sshfs) mount
is used as a volume without specifying ro flag, the kernel fails
to remount it (when adding various flags such as nosuid and nodev),
returning EPERM.
Here's the relevant strace line:
> [pid 333966] mount("/tmp/bats-run-PRVfWc/runc.RbNv8g/bundle/mnt", "/proc/self/fd/7", 0xc0001e9164, MS_NOSUID|MS_NODEV|MS_REMOUNT|MS_BIND|MS_REC, NULL) = -1 EPERM (Operation not permitted)
I was not able to reproduce it with other read-only mounts as the source
(tried tmpfs, read-only bind mount, and an ext2 mount), so somehow this
might be specific to fuse.
The fix is to check whether the source has RDONLY flag, and retry the
remount with this flag added.
A test case (which was kind of hard to write) is added, and it fails
without the fix. Note that rootless user need to be able to ssh to
rootless@localhost in order to sshfs to work -- amend setup scripts
to make it work, and skip the test if the setup is not working.
[1] containers/podman#12205
Signed-off-by: Kir Kolyshkin <[email protected]>
20e15a2 to
50105de
Compare
|
@thaJeztah PTAL |
|
This fixes a real bug and we need to backport it to 1.0.3. Can this be merged? PTAL @opencontainers/runc-maintainers |
|
Ahm, sorry, I started looking, but got pulled away |
| if err == nil { | ||
| return nil | ||
| } | ||
| // Check if the source has ro flag... |
There was a problem hiding this comment.
Meta question: Can this be solved by requiring the entity configuring the mounts to set the necessary flags?
There was a problem hiding this comment.
Yes, but it's not clear who should handle this (e.g. podman thinks it shouldn't, see containers/podman#12205) , and handling it in runc is kind of trivial. Besides, crun already does this, and this makes it hard to convince upper layers should do this.
As reported in containers/podman#12205, in a case where read-only fuse (sshfs)
mount is used as a volume without specifying ro flag, the kernel fails
to remount it (when adding various flags such as nosuid and nodev),
returning EPERM.
Here's the relevant strace line:
I was not able to reproduce it with other read-only mounts as the source
(tried tmpfs, read-only bind mount, and an ext2 mount), so somehow this
might be specific to fuse.
The fix is to check whether the source has RDONLY flag, and retry the
remount with this flag added.
A test case (which was kind of hard to write) is added, and it fails
without the fix:
Note that rootless user need to be able to ssh to rootless@localhost
in order to sshfs to work -- amend setup scripts to make it work.
1.0 backport: #3292