Download raw body.
fuse: allow control of the MNT_LOCAL flag
On Thu, May 02, 2024 at 01:47:54PM +0200, Kirill A. Korinsky wrote:
> tech@,
>
> May I ask you to review this patch?
>
> FUSE is a rather unique FS that can be used to mount local files like a
> zip archive and remote resources like sshfs.
>
> So, such a system should not always be mounted with MNT_LOCAL, which is
> seen as a local flag by mount. This flag can be used by various filters
> to avoid running on non-local FS.
>
> For example, /usr/libexec/security walks over mounted via FUSE sshfs and
> other network FS because it has this flag.
>
> So the proposed patch allows to control this flag via FUSE mount
> options, and inside the driver as fuse_opt_insert_arg with -ononlocal.
>
> No other FS is affected by this change and MNT_LOCAL is ignored.
>
> It also doesn't change current behavior on existing drivers, to remove the
> MNT_LOCAL flag the fuse driver needs to be patched, or the user should add a
> commind line argument.
>
> This patch has been tested on -curent/amd64 using sshfs.
>
> P.S. This is a cleaner solution than ignoring fuse in libexec/security.
>
I see FreeBSD just clears [1] MNT_LOCAL flag and this looks reasonable
to me.
1. https://lists.freebsd.org/pipermail/svn-src-projects/2019-May/013565.html
> diff --git lib/libfuse/fuse.c lib/libfuse/fuse.c
> index 2b8c0ebdfc6..51e560ff6d5 100644
> --- lib/libfuse/fuse.c
> +++ lib/libfuse/fuse.c
> @@ -106,6 +106,7 @@ static struct fuse_opt fuse_mount_opts[] = {
> FUSE_OPT_KEY("max_write", KEY_STUB),
> FUSE_MOUNT_OPT("noatime", noatime),
> FUSE_MOUNT_OPT("nonempty", nonempty),
> + FUSE_MOUNT_OPT("nonlocal", nonlocal),
> FUSE_MOUNT_OPT("-r", rdonly),
> FUSE_MOUNT_OPT("ro", rdonly),
> FUSE_OPT_KEY("ro_fallback", KEY_STUB),
> @@ -302,6 +303,8 @@ fuse_mount(const char *dir, struct fuse_args *args)
> mnt_flags |= MNT_RDONLY;
> if (opts.noatime)
> mnt_flags |= MNT_NOATIME;
> + if (!opts.nonlocal)
> + mnt_flags |= MNT_LOCAL;
>
> if (opts.max_read > FUSEBUFMAXSIZE) {
> fprintf(stderr, "fuse: invalid max_read (%d > %d)\n",
> diff --git lib/libfuse/fuse_private.h lib/libfuse/fuse_private.h
> index 208c997828a..438100bf0b9 100644
> --- lib/libfuse/fuse_private.h
> +++ lib/libfuse/fuse_private.h
> @@ -95,6 +95,7 @@ struct fuse_mount_opts {
> int noatime;
> int nonempty;
> int rdonly;
> + int nonlocal;
> };
>
> struct fuse {
> diff --git sys/kern/vfs_syscalls.c sys/kern/vfs_syscalls.c
> index 40445f251bf..906653947ee 100644
> --- sys/kern/vfs_syscalls.c
> +++ sys/kern/vfs_syscalls.c
> @@ -243,6 +243,14 @@ update:
> mp->mnt_flag |= flags & (MNT_NOSUID | MNT_NOEXEC | MNT_WXALLOWED |
> MNT_NODEV | MNT_SYNCHRONOUS | MNT_ASYNC | MNT_NOATIME | MNT_NOPERM |
> MNT_FORCE);
> +
> +#ifdef FUSE
> + if (strcmp(vfsp->vfc_name, MOUNT_FUSEFS) == 0) {
> + mp->mnt_flag &=~ MNT_LOCAL;
> + mp->mnt_flag |= flags & MNT_LOCAL;
> + }
> +#endif
> +
> /*
> * Mount the filesystem.
> */
> diff --git sys/miscfs/fuse/fuse_vfsops.c sys/miscfs/fuse/fuse_vfsops.c
> index 5b30b1544aa..9e2fc0060fd 100644
> --- sys/miscfs/fuse/fuse_vfsops.c
> +++ sys/miscfs/fuse/fuse_vfsops.c
> @@ -114,7 +114,6 @@ fusefs_mount(struct mount *mp, const char *path, void *data,
> fmp->allow_other = args->allow_other;
>
> mp->mnt_data = fmp;
> - mp->mnt_flag |= MNT_LOCAL;
> vfs_getnewfsid(mp);
>
> memset(mp->mnt_stat.f_mntonname, 0, MNAMELEN);
>
>
> --
> wbr, Kirill
>
fuse: allow control of the MNT_LOCAL flag