|
@@ -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);
|