diff options
author | 2018-06-19 13:01:34 +0000 | |
---|---|---|
committer | 2018-06-19 13:01:34 +0000 | |
commit | 0f4d2db5a50672bad418a08041219503c0deeced (patch) | |
tree | b696440c584926d866e76b1253f75c0bbc0ae8f0 | |
parent | Revert previous, there were some unintended beviour changes. (diff) | |
download | wireguard-openbsd-0f4d2db5a50672bad418a08041219503c0deeced.tar.xz wireguard-openbsd-0f4d2db5a50672bad418a08041219503c0deeced.zip |
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@
-rw-r--r-- | lib/libfuse/fuse.c | 9 | ||||
-rw-r--r-- | lib/libfuse/fuse_private.h | 3 | ||||
-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 |
6 files changed, 76 insertions, 15 deletions
diff --git a/lib/libfuse/fuse.c b/lib/libfuse/fuse.c index 9ed4079c5ba..db0fdfa94f0 100644 --- a/lib/libfuse/fuse.c +++ b/lib/libfuse/fuse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse.c,v 1.46 2018/06/19 11:27:54 helg Exp $ */ +/* $OpenBSD: fuse.c,v 1.47 2018/06/19 13:01:34 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com> * @@ -64,8 +64,6 @@ static struct fuse_opt fuse_core_opts[] = { #define FUSE_LIB_OPT(o, m) {o, offsetof(struct fuse_config, m), 1} static struct fuse_opt fuse_lib_opts[] = { FUSE_OPT_KEY("ac_attr_timeout=", KEY_STUB), - FUSE_OPT_KEY("allow_other", KEY_STUB), - FUSE_OPT_KEY("allow_root", KEY_STUB), FUSE_OPT_KEY("attr_timeout=", KEY_STUB), FUSE_OPT_KEY("auto_cache", KEY_STUB), FUSE_OPT_KEY("noauto_cache", KEY_STUB), @@ -97,6 +95,8 @@ static struct fuse_opt fuse_lib_opts[] = { /* options supported by fuse_mount */ #define FUSE_MOUNT_OPT(o, m) {o, offsetof(struct fuse_mount_opts, m), 1} static struct fuse_opt fuse_mount_opts[] = { + FUSE_MOUNT_OPT("allow_other", allow_other), + FUSE_OPT_KEY("allow_root", KEY_STUB), FUSE_OPT_KEY("async_read", KEY_STUB), FUSE_OPT_KEY("blkdev", KEY_STUB), FUSE_OPT_KEY("blksize=", KEY_STUB), @@ -253,6 +253,7 @@ fuse_loop(struct fuse *fuse) ioexch.fbxch_data = fbuf.fb_dat; if (ioctl(fuse->fc->fd, FIOCSETFBDAT, &ioexch)) { +printf("libfuse: FIOCSETFBDAT error\n"); free(fbuf.fb_dat); return (-1); } @@ -261,6 +262,7 @@ fuse_loop(struct fuse *fuse) ictx = NULL; if (n != FUSEBUFSIZE) { +printf("libfuse: write error: %s\n", strerror(errno)); errno = EINVAL; return (-1); } @@ -315,6 +317,7 @@ fuse_mount(const char *dir, struct fuse_args *args) memset(&fargs, 0, sizeof(fargs)); fargs.fd = fc->fd; fargs.max_read = opts.max_read; + fargs.allow_other = opts.allow_other; if (mount(MOUNT_FUSEFS, fc->dir, mnt_flags, &fargs)) { switch (errno) { diff --git a/lib/libfuse/fuse_private.h b/lib/libfuse/fuse_private.h index 5dc163abcba..c3f1f659dfb 100644 --- a/lib/libfuse/fuse_private.h +++ b/lib/libfuse/fuse_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_private.h,v 1.20 2018/06/07 22:28:11 helg Exp $ */ +/* $OpenBSD: fuse_private.h,v 1.21 2018/06/19 13:01:34 helg Exp $ */ /* * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com> * @@ -90,6 +90,7 @@ struct fuse_core_opts { struct fuse_mount_opts { char *fsname; + int allow_other; int def_perms; int max_read; int noatime; 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; }; /* |