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;
{
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);
/** 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;
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
opt_uid,
opt_default_permissions,
opt_allow_other,
+ opt_allow_root,
opt_kernel_cache,
opt_large_read,
opt_direct_io,
{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"},
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;
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
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;