mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
fuse: support idmapped FUSE_EXT_GROUPS
We don't need to remap parent_gid, but have to adjust group membership checks and take idmapping into account. Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
10dc721836
commit
d561254fb7
@ -545,17 +545,21 @@ static u32 fuse_ext_size(size_t size)
|
||||
/*
|
||||
* This adds just a single supplementary group that matches the parent's group.
|
||||
*/
|
||||
static int get_create_supp_group(struct inode *dir, struct fuse_in_arg *ext)
|
||||
static int get_create_supp_group(struct mnt_idmap *idmap,
|
||||
struct inode *dir,
|
||||
struct fuse_in_arg *ext)
|
||||
{
|
||||
struct fuse_conn *fc = get_fuse_conn(dir);
|
||||
struct fuse_ext_header *xh;
|
||||
struct fuse_supp_groups *sg;
|
||||
kgid_t kgid = dir->i_gid;
|
||||
vfsgid_t vfsgid = make_vfsgid(idmap, fc->user_ns, kgid);
|
||||
gid_t parent_gid = from_kgid(fc->user_ns, kgid);
|
||||
|
||||
u32 sg_len = fuse_ext_size(sizeof(*sg) + sizeof(sg->groups[0]));
|
||||
|
||||
if (parent_gid == (gid_t) -1 || gid_eq(kgid, current_fsgid()) ||
|
||||
!in_group_p(kgid))
|
||||
if (parent_gid == (gid_t) -1 || vfsgid_eq_kgid(vfsgid, current_fsgid()) ||
|
||||
!vfsgid_in_group_p(vfsgid))
|
||||
return 0;
|
||||
|
||||
xh = extend_arg(ext, sg_len);
|
||||
@ -572,7 +576,8 @@ static int get_create_supp_group(struct inode *dir, struct fuse_in_arg *ext)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_create_ext(struct fuse_args *args,
|
||||
static int get_create_ext(struct mnt_idmap *idmap,
|
||||
struct fuse_args *args,
|
||||
struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
@ -583,7 +588,7 @@ static int get_create_ext(struct fuse_args *args,
|
||||
if (fc->init_security)
|
||||
err = get_security_context(dentry, mode, &ext);
|
||||
if (!err && fc->create_supp_group)
|
||||
err = get_create_supp_group(dir, &ext);
|
||||
err = get_create_supp_group(idmap, dir, &ext);
|
||||
|
||||
if (!err && ext.size) {
|
||||
WARN_ON(args->in_numargs >= ARRAY_SIZE(args->in_args));
|
||||
@ -668,7 +673,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||
args.out_args[1].size = sizeof(*outopenp);
|
||||
args.out_args[1].value = outopenp;
|
||||
|
||||
err = get_create_ext(&args, dir, entry, mode);
|
||||
err = get_create_ext(&nop_mnt_idmap, &args, dir, entry, mode);
|
||||
if (err)
|
||||
goto out_free_ff;
|
||||
|
||||
@ -798,7 +803,7 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
|
||||
args->out_args[0].value = &outarg;
|
||||
|
||||
if (args->opcode != FUSE_LINK) {
|
||||
err = get_create_ext(args, dir, entry, mode);
|
||||
err = get_create_ext(&nop_mnt_idmap, args, dir, entry, mode);
|
||||
if (err)
|
||||
goto out_put_forget_req;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user