From 180ff6921b1d995194c159729c5d494b07b802ca Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Nov 2004 16:01:05 +0000 Subject: [PATCH] new mount option --- kernel/dir.c | 7 +++++-- kernel/fuse_i.h | 4 ++++ kernel/inode.c | 13 +++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/kernel/dir.c b/kernel/dir.c index 87dec6a..36eb3bf 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -505,7 +505,9 @@ static int fuse_revalidate(struct dentry *entry) if (inode->i_ino == FUSE_ROOT_INO) { if (!(fc->flags & FUSE_ALLOW_OTHER) && - current->fsuid != fc->uid) + current->fsuid != fc->uid && + (!(fc->flags & FUSE_ALLOW_ROOT) || + current->fsuid != 0)) return -EACCES; } else if (!fi->i_time || time_before_eq(jiffies, fi->i_time)) return 0; @@ -517,7 +519,8 @@ static int _fuse_permission(struct inode *inode, int mask) { struct fuse_conn *fc = INO_FC(inode); - if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid) + if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid && + (!(fc->flags & FUSE_ALLOW_ROOT) || current->fsuid != 0)) return -EACCES; else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { int err = vfs_permission(inode, mask); diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index 5a4d7e7..8e3b416 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -73,6 +73,10 @@ permission checking is done in the kernel */ /** Bypass the page cache for read and write operations */ #define FUSE_DIRECT_IO (1 << 3) +/** Allow root and setuid-root programs to access fuse-mounted + filesystems */ +#define FUSE_ALLOW_ROOT (1 << 4) + /** FUSE specific inode data */ struct fuse_inode { struct fuse_req *forget_req; diff --git a/kernel/inode.c b/kernel/inode.c index 09479e1..8de566c 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -33,7 +33,7 @@ module_param(user_allow_other, int, 0); MODULE_PARM(user_allow_other, "i"); #endif -MODULE_PARM_DESC(user_allow_other, "Allow non root user to specify the \"allow_other\" mount option"); +MODULE_PARM_DESC(user_allow_other, "Allow non root user to specify the \"allow_other\" or \"allow_root\" mount options"); #define FUSE_SUPER_MAGIC 0x65735546 @@ -176,6 +176,7 @@ enum { opt_fd, opt_uid, opt_default_permissions, opt_allow_other, + opt_allow_root, opt_kernel_cache, opt_large_read, opt_direct_io, @@ -188,6 +189,7 @@ static match_table_t tokens = { {opt_uid, "uid=%u"}, {opt_default_permissions, "default_permissions"}, {opt_allow_other, "allow_other"}, + {opt_allow_root, "allow_root"}, {opt_kernel_cache, "kernel_cache"}, {opt_large_read, "large_read"}, {opt_direct_io, "direct_io"}, @@ -237,6 +239,10 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) d->flags |= FUSE_ALLOW_OTHER; break; + case opt_allow_root: + d->flags |= FUSE_ALLOW_ROOT; + break; + case opt_kernel_cache: d->flags |= FUSE_KERNEL_CACHE; break; @@ -284,6 +290,8 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) seq_puts(m, ",default_permissions"); if (fc->flags & FUSE_ALLOW_OTHER) seq_puts(m, ",allow_other"); + if (fc->flags & FUSE_ALLOW_ROOT) + seq_puts(m, ",allow_root"); if (fc->flags & FUSE_KERNEL_CACHE) seq_puts(m, ",kernel_cache"); #ifndef KERNEL_2_6 @@ -375,7 +383,8 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent) if (!parse_fuse_opt((char *) data, &d)) return -EINVAL; - if (!user_allow_other && (d.flags & FUSE_ALLOW_OTHER) && + if (!user_allow_other && + (d.flags & (FUSE_ALLOW_OTHER | FUSE_ALLOW_ROOT)) && current->uid != 0) return -EPERM; -- 2.30.2