Hi Jason,
On Tue, Apr 16, 2019 at 04:14:13PM -0700, Jason Boles wrote:
> Thanks for the reply, I checked out your links, fuserpremount.c &
> fuse-premount.c,modified sshfs (release 3.5.2 has your changes), and read
> the libfuse 3.3.0 release notes that introduce /dev/fd/%u feature, but I
> think I still have a fundamental misunderstanding of how /dev/fd/* relates
> to /dev/fuse w.r.t. containers.
>
> I've also tested on Fedora 29 host w/'fedora:latest' Docker container,
> passing device=/dev/fuse into the container. When I run it without
> --privileged, the premount fails in the same way that fusermount3 fails,
> because setuid root doesn't actually become root.
>
> --: mount failed: Operation not permitted
> fuserpremount: failed to receive fd from fusermount
>
>
> So, does that mean that I'd have to pre-mount (i.e. get a unique file
> descriptor) then assign that to --device=/dev/fd/blah as a parameter to the
> container at runtime, then inside the container run the fuse-command? (If
> so, this is workable, but not ideal)
Oh, I hadn't tried it with docker in the way yet. I tried a
fuse-premount with docker run just now, with the command to run being a
shell script that just prints the parameter and runs bash so I can do
what I want with it and the last parameter a writable mount point as
fuse-premount expects:
./fuse-premount docker run --rm -it fedora:latest /tmp/bashit $HOME/tmp/mnt
and I got an error from docker:
docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:359: container init caused \"rootfs_linux.go:43: preparing rootfs caused \\\"Error found less than 3 fields post '-' in \\\\\\\"825 824 0:110 / /cloud/login/dwd/tmp/mnt rw,relatime - fuse rw,user_id=3382,group_id=9996\\\\\\\"\\\"\"".
ERRO[0000] error getting events from daemon: context canceled
I got around that by changing the first parameter sent to the mount command
in fuse-premount.c to "fuse", and added "-v /tmp/bashit:/tmp/bashit" to
map the script inside the container.
I then found that the file descriptor created by fuse-premount was not
passed in to the docker container. I'm quite sure that's because docker
containers aren't created as children of the docker process, they are
children of the docker-containerd daemon. So that's probably never
going to work unless there's some option to pass selected file
descriptors through (like fuserpremount does) but I don't see such an
existing option.
I haven't been able to get fuse-premount to work with singularity yet
either, because somewhere during initialization singularity tries to do
an fstat on the open file descriptor, and it hangs because there's
nothing yet implementing the fuse filesystem. It's not obvious where
this is happening. I think we'll just need to wait for the singularity
--fusecmd option, or maybe it would work in some other daemonless
container system like podman.
> Ideally, I'd like to run each container with device=/dev/fuse, then inside
> the unprivileged container mount the fuse-based filesystem. Even if that
> means that the host requires kernel 4.18+ and libfuse3.3+ and the container
> requires libfuse 3.3+, and the fuse filesystem inside the container must
> make the function calls to libfuse, rather than exec'ing fusermount3.
>
> Inside my test container, I see this behavior:
>
> [root@f3b78b593c16 ~]# sshfs user@host: /mnt/ssh
> fusermount3: mount failed: Operation not permitted
> [root@f3b78b593c16 ~]# rpm -e --nodeps fuse3
> [root@f3b78b593c16 ~]# sshfs user@host: /mnt/ssh
> fuse: failed to exec fusermount3: No such file or directory
> [root@f3b78b593c16 ~]# fuse-premount sshfs user@host: /mnt/ssh
> fuse-premount: failed to mount -o fd=3,rootmode=40000,user_id=0,group_id=0
> /dev/fuse /mnt/ssh: Operation not permitted
>
>
> (note above fuse-premount.c commented out "if (geteuid() != 0 || getuid()
> == 0) {}" test block...)
>
> The use case is automated testing of buggy/unreliable fuse filesystems
> (student code) in a shared Docker environment where privileged mode is
> disabled.
Oh, if you're willing to user linux kernel 4.18+ then you don't even
need libfuse3.
Just run "unshare -Ufirmp". That gets you a fake root unprivileged user
namespace. Then just run sshfs giving it a mount point of some empty
directory that you have write access to. I haven't tried it in
unprivileged docker yet, but it should work.
Dave
> To unsubscribe from this group and stop receiving emails from it, send an email to
singularity...@lbl.gov.