summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorhelg <helg@cvs.openbsd.org>2018-06-19 13:01:35 +0000
committerhelg <helg@cvs.openbsd.org>2018-06-19 13:01:35 +0000
commite1988567feb2b90bc2aa8bce70b2547033a7c1c9 (patch)
treeea2d50ac060d28ba16aed341e9c985edb0377d5e /sys
parenta175a801354e4e0d28551a9058a0c863119ec755 (diff)
Changes the default mount behaviour so only the user that mounts the
file system can access it unless the allow_other mount options is specified. The allow_other mount option makes the file system available to other users just like any other mounted file system. ok mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/miscfs/fuse/fuse_vfsops.c11
-rw-r--r--sys/miscfs/fuse/fuse_vnops.c54
-rw-r--r--sys/miscfs/fuse/fusefs.h3
-rw-r--r--sys/sys/mount.h11
4 files changed, 68 insertions, 11 deletions
diff --git a/sys/miscfs/fuse/fuse_vfsops.c b/sys/miscfs/fuse/fuse_vfsops.c
index acfa712dbdb..2b9db65077b 100644
--- a/sys/miscfs/fuse/fuse_vfsops.c
+++ b/sys/miscfs/fuse/fuse_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vfsops.c,v 1.37 2018/05/20 03:06:50 helg Exp $ */
+/* $OpenBSD: fuse_vfsops.c,v 1.38 2018/06/19 13:01:34 helg Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -107,6 +107,11 @@ fusefs_mount(struct mount *mp, const char *path, void *data,
else
fmp->max_read = FUSEBUFMAXSIZE;
+ /* Only root may specify allow_other. */
+ if (args->allow_other && (error = suser_ucred(p->p_ucred)))
+ return (error);
+ fmp->allow_other = args->allow_other;
+
mp->mnt_data = fmp;
mp->mnt_flag |= MNT_LOCAL;
vfs_getnewfsid(mp);
@@ -202,6 +207,10 @@ fusefs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
fmp = VFSTOFUSEFS(mp);
+ /* Deny other users unless allow_other mount option was specified. */
+ if (!fmp->allow_other && p->p_ucred->cr_uid != mp->mnt_stat.f_owner)
+ return (EPERM);
+
copy_statfs_info(sbp, mp);
/*
diff --git a/sys/miscfs/fuse/fuse_vnops.c b/sys/miscfs/fuse/fuse_vnops.c
index 322786af7c7..62325073b48 100644
--- a/sys/miscfs/fuse/fuse_vnops.c
+++ b/sys/miscfs/fuse/fuse_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fuse_vnops.c,v 1.46 2018/06/18 12:04:20 helg Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.47 2018/06/19 13:01:34 helg Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -330,6 +330,13 @@ fusefs_access(void *v)
ip = VTOI(ap->a_vp);
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
+ /*
+ * Only user that mounted the file system can access it unless
+ * allow_other mount option was specified.
+ */
+ if (!fmp->allow_other && cred->cr_uid != fmp->mp->mnt_stat.f_owner)
+ return (EACCES);
+
if (!fmp->sess_init)
return (ENXIO);
@@ -365,6 +372,7 @@ fusefs_getattr(void *v)
struct fusefs_mnt *fmp;
struct vattr *vap = ap->a_vap;
struct proc *p = ap->a_p;
+ struct ucred *cred = p->p_ucred;
struct fusefs_node *ip;
struct fusebuf *fbuf;
struct stat *st;
@@ -373,6 +381,33 @@ fusefs_getattr(void *v)
ip = VTOI(vp);
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
+ /*
+ * Only user that mounted the file system can access it unless
+ * allow_other mount option was specified. Return dummy values
+ * for the root inode in this situation.
+ */
+ if (!fmp->allow_other && cred->cr_uid != fmp->mp->mnt_stat.f_owner) {
+ VATTR_NULL(vap);
+ vap->va_type = VNON;
+ if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ vap->va_mode = S_IRUSR | S_IXUSR;
+ else
+ vap->va_mode = S_IRWXU;
+ vap->va_nlink = 1;
+ vap->va_uid = fmp->mp->mnt_stat.f_owner;
+ vap->va_gid = fmp->mp->mnt_stat.f_owner;
+ vap->va_fsid = fmp->mp->mnt_stat.f_fsid.val[0];
+ vap->va_fileid = ip->ufs_ino.i_number;
+ vap->va_size = S_BLKSIZE;
+ vap->va_blocksize = S_BLKSIZE;
+ vap->va_atime.tv_sec = fmp->mp->mnt_stat.f_ctime;
+ vap->va_mtime.tv_sec = fmp->mp->mnt_stat.f_ctime;
+ vap->va_ctime.tv_sec = fmp->mp->mnt_stat.f_ctime;
+ vap->va_rdev = fmp->dev;
+ vap->va_bytes = S_BLKSIZE;
+ return (0);
+ }
+
if (!fmp->sess_init)
return (ENXIO);
@@ -851,15 +886,16 @@ fusefs_reclaim(void *v)
{
struct vop_reclaim_args *ap = v;
struct vnode *vp = ap->a_vp;
+ struct proc *p = ap->a_p;
struct fusefs_node *ip = VTOI(vp);
struct fusefs_filehandle *fufh = NULL;
struct fusefs_mnt *fmp;
struct fusebuf *fbuf;
- int type;
+ int type, error = 0;
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
- /*close opened files*/
+ /* Close opened files. */
for (type = 0; type < FUFH_MAXTYPE; type++) {
fufh = &(ip->fufh[type]);
if (fufh->fh_type != FUFH_INVALID) {
@@ -870,13 +906,13 @@ fusefs_reclaim(void *v)
}
/*
- * if the fuse connection is opened
- * ask libfuse to free the vnodes
+ * If the fuse connection is opened ask libfuse to free the vnodes.
*/
if (fmp->sess_init && ip->ufs_ino.i_number != FUSE_ROOTINO) {
- fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_RECLAIM, ap->a_p);
- if (fb_queue(fmp->dev, fbuf))
- printf("fusefs: libfuse vnode reclaim failed\n");
+ fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_RECLAIM, p);
+ error = fb_queue(fmp->dev, fbuf);
+ if (error)
+ printf("fusefs: vnode reclaim failed: %d\n", error);
fb_delete(fbuf);
}
@@ -887,6 +923,8 @@ fusefs_reclaim(void *v)
free(ip, M_FUSEFS, sizeof(*ip));
vp->v_data = NULL;
+
+ /* Must return success otherwise kernel panic in vclean(9). */
return (0);
}
diff --git a/sys/miscfs/fuse/fusefs.h b/sys/miscfs/fuse/fusefs.h
index bf2c1f34c3a..cf318150c97 100644
--- a/sys/miscfs/fuse/fusefs.h
+++ b/sys/miscfs/fuse/fusefs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fusefs.h,v 1.9 2018/05/20 02:51:26 helg Exp $ */
+/* $OpenBSD: fusefs.h,v 1.10 2018/06/19 13:01:34 helg Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
@@ -52,6 +52,7 @@ struct fusefs_mnt {
uint32_t undef_op;
int max_read;
int sess_init;
+ int allow_other;
dev_t dev;
};
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 2148f7c0449..d1ebe2d2d15 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.137 2018/06/04 04:57:09 guenther Exp $ */
+/* $OpenBSD: mount.h,v 1.138 2018/06/19 13:01:34 helg Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -246,6 +246,15 @@ struct fusefs_args {
char *name;
int fd;
int max_read;
+
+ /*
+ * FUSE does not allow the file system to be accessed by other users
+ * unless this option is specified. This is to prevent unintentional
+ * denial of service to other users if the file system is not
+ * responding. e.g. user executes df(1) or cron job that scans mounted
+ * file systems.
+ */
+ int allow_other;
};
/*