fs: introduce fsuidgid_has_mapping() helper
Don't open-code the checks and instead move them into a clean little helper we can call. This also reduces the risk that if we ever change something we forget to change all locations. Link: https://lore.kernel.org/r/20210320122623.599086-4-christian.brauner@ubuntu.com Inspired-by: Vivek Goyal <vgoyal@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Родитель
a65e58e791
Коммит
8e5389132a
11
fs/namei.c
11
fs/namei.c
|
@ -2823,16 +2823,14 @@ static int may_delete(struct user_namespace *mnt_userns, struct inode *dir,
|
|||
static inline int may_create(struct user_namespace *mnt_userns,
|
||||
struct inode *dir, struct dentry *child)
|
||||
{
|
||||
struct user_namespace *s_user_ns;
|
||||
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
||||
if (child->d_inode)
|
||||
return -EEXIST;
|
||||
if (IS_DEADDIR(dir))
|
||||
return -ENOENT;
|
||||
s_user_ns = dir->i_sb->s_user_ns;
|
||||
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
|
||||
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
|
||||
if (!fsuidgid_has_mapping(dir->i_sb, mnt_userns))
|
||||
return -EOVERFLOW;
|
||||
|
||||
return inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC);
|
||||
}
|
||||
|
||||
|
@ -3034,14 +3032,11 @@ static int may_o_create(struct user_namespace *mnt_userns,
|
|||
const struct path *dir, struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct user_namespace *s_user_ns;
|
||||
int error = security_path_mknod(dir, dentry, mode, 0);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
s_user_ns = dir->dentry->d_sb->s_user_ns;
|
||||
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
|
||||
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
|
||||
if (!fsuidgid_has_mapping(dir->dentry->d_sb, mnt_userns))
|
||||
return -EOVERFLOW;
|
||||
|
||||
error = inode_permission(mnt_userns, dir->dentry->d_inode,
|
||||
|
|
|
@ -1692,6 +1692,26 @@ static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns)
|
|||
return kgid_from_mnt(mnt_userns, current_fsgid());
|
||||
}
|
||||
|
||||
/**
|
||||
* fsuidgid_has_mapping() - check whether caller's fsuid/fsgid is mapped
|
||||
* @sb: the superblock we want a mapping in
|
||||
* @mnt_userns: user namespace of the relevant mount
|
||||
*
|
||||
* Check whether the caller's fsuid and fsgid have a valid mapping in the
|
||||
* s_user_ns of the superblock @sb. If the caller is on an idmapped mount map
|
||||
* the caller's fsuid and fsgid according to the @mnt_userns first.
|
||||
*
|
||||
* Return: true if fsuid and fsgid is mapped, false if not.
|
||||
*/
|
||||
static inline bool fsuidgid_has_mapping(struct super_block *sb,
|
||||
struct user_namespace *mnt_userns)
|
||||
{
|
||||
struct user_namespace *s_user_ns = sb->s_user_ns;
|
||||
|
||||
return kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) &&
|
||||
kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns));
|
||||
}
|
||||
|
||||
extern struct timespec64 current_time(struct inode *inode);
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче