Merge tag 'for-linus-20130204' of git://git.infradead.org/linux-mtd
[cascardo/linux.git] / fs / fuse / inode.c
index f0eda12..73ca6b7 100644 (file)
@@ -60,8 +60,8 @@ MODULE_PARM_DESC(max_user_congthresh,
 struct fuse_mount_data {
        int fd;
        unsigned rootmode;
-       unsigned user_id;
-       unsigned group_id;
+       kuid_t user_id;
+       kgid_t group_id;
        unsigned fd_present:1;
        unsigned rootmode_present:1;
        unsigned user_id_present:1;
@@ -164,8 +164,8 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
        inode->i_ino     = fuse_squash_ino(attr->ino);
        inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
        set_nlink(inode, attr->nlink);
-       inode->i_uid     = attr->uid;
-       inode->i_gid     = attr->gid;
+       inode->i_uid     = make_kuid(&init_user_ns, attr->uid);
+       inode->i_gid     = make_kgid(&init_user_ns, attr->gid);
        inode->i_blocks  = attr->blocks;
        inode->i_atime.tv_sec   = attr->atime;
        inode->i_atime.tv_nsec  = attr->atimensec;
@@ -492,14 +492,18 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
                case OPT_USER_ID:
                        if (match_int(&args[0], &value))
                                return 0;
-                       d->user_id = value;
+                       d->user_id = make_kuid(current_user_ns(), value);
+                       if (!uid_valid(d->user_id))
+                               return 0;
                        d->user_id_present = 1;
                        break;
 
                case OPT_GROUP_ID:
                        if (match_int(&args[0], &value))
                                return 0;
-                       d->group_id = value;
+                       d->group_id = make_kgid(current_user_ns(), value);
+                       if (!gid_valid(d->group_id))
+                               return 0;
                        d->group_id_present = 1;
                        break;
 
@@ -540,8 +544,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
        struct super_block *sb = root->d_sb;
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
-       seq_printf(m, ",user_id=%u", fc->user_id);
-       seq_printf(m, ",group_id=%u", fc->group_id);
+       seq_printf(m, ",user_id=%u", from_kuid_munged(&init_user_ns, fc->user_id));
+       seq_printf(m, ",group_id=%u", from_kgid_munged(&init_user_ns, fc->group_id));
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
                seq_puts(m, ",default_permissions");
        if (fc->flags & FUSE_ALLOW_OTHER)
@@ -989,7 +993,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        if (!file)
                goto err;
 
-       if (file->f_op != &fuse_dev_operations)
+       if ((file->f_op != &fuse_dev_operations) ||
+           (file->f_cred->user_ns != &init_user_ns))
                goto err_fput;
 
        fc = kmalloc(sizeof(*fc), GFP_KERNEL);