summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhelg <helg@openbsd.org>2018-06-19 13:01:34 +0000
committerhelg <helg@openbsd.org>2018-06-19 13:01:34 +0000
commit0f4d2db5a50672bad418a08041219503c0deeced (patch)
treeb696440c584926d866e76b1253f75c0bbc0ae8f0
parentRevert previous, there were some unintended beviour changes. (diff)
downloadwireguard-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.c9
-rw-r--r--lib/libfuse/fuse_private.h3
-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
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;
};
/*