diff options
author | helg <helg@cvs.openbsd.org> | 2018-06-19 13:01:35 +0000 |
---|---|---|
committer | helg <helg@cvs.openbsd.org> | 2018-06-19 13:01:35 +0000 |
commit | e1988567feb2b90bc2aa8bce70b2547033a7c1c9 (patch) | |
tree | ea2d50ac060d28ba16aed341e9c985edb0377d5e /sys | |
parent | a175a801354e4e0d28551a9058a0c863119ec755 (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.c | 11 | ||||
-rw-r--r-- | sys/miscfs/fuse/fuse_vnops.c | 54 | ||||
-rw-r--r-- | sys/miscfs/fuse/fusefs.h | 3 | ||||
-rw-r--r-- | sys/sys/mount.h | 11 |
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; }; /* |