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,
|
static inline int may_create(struct user_namespace *mnt_userns,
|
||||||
struct inode *dir, struct dentry *child)
|
struct inode *dir, struct dentry *child)
|
||||||
{
|
{
|
||||||
struct user_namespace *s_user_ns;
|
|
||||||
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
||||||
if (child->d_inode)
|
if (child->d_inode)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (IS_DEADDIR(dir))
|
if (IS_DEADDIR(dir))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
s_user_ns = dir->i_sb->s_user_ns;
|
if (!fsuidgid_has_mapping(dir->i_sb, mnt_userns))
|
||||||
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
|
|
||||||
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
|
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
|
|
||||||
return inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC);
|
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,
|
const struct path *dir, struct dentry *dentry,
|
||||||
umode_t mode)
|
umode_t mode)
|
||||||
{
|
{
|
||||||
struct user_namespace *s_user_ns;
|
|
||||||
int error = security_path_mknod(dir, dentry, mode, 0);
|
int error = security_path_mknod(dir, dentry, mode, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
s_user_ns = dir->dentry->d_sb->s_user_ns;
|
if (!fsuidgid_has_mapping(dir->dentry->d_sb, mnt_userns))
|
||||||
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
|
|
||||||
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
|
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
|
|
||||||
error = inode_permission(mnt_userns, dir->dentry->d_inode,
|
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());
|
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);
|
extern struct timespec64 current_time(struct inode *inode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче