Download raw body.
fuse: allow control of the MNT_LOCAL flag
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.
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