Skip to content

Commit 8e53891

Browse files
author
Christian Brauner
committed
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/[email protected] Inspired-by: Vivek Goyal <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Al Viro <[email protected]> Cc: [email protected] Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent a65e58e commit 8e53891

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

fs/namei.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,16 +2823,14 @@ static int may_delete(struct user_namespace *mnt_userns, struct inode *dir,
28232823
static inline int may_create(struct user_namespace *mnt_userns,
28242824
struct inode *dir, struct dentry *child)
28252825
{
2826-
struct user_namespace *s_user_ns;
28272826
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
28282827
if (child->d_inode)
28292828
return -EEXIST;
28302829
if (IS_DEADDIR(dir))
28312830
return -ENOENT;
2832-
s_user_ns = dir->i_sb->s_user_ns;
2833-
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
2834-
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
2831+
if (!fsuidgid_has_mapping(dir->i_sb, mnt_userns))
28352832
return -EOVERFLOW;
2833+
28362834
return inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC);
28372835
}
28382836

@@ -3034,14 +3032,11 @@ static int may_o_create(struct user_namespace *mnt_userns,
30343032
const struct path *dir, struct dentry *dentry,
30353033
umode_t mode)
30363034
{
3037-
struct user_namespace *s_user_ns;
30383035
int error = security_path_mknod(dir, dentry, mode, 0);
30393036
if (error)
30403037
return error;
30413038

3042-
s_user_ns = dir->dentry->d_sb->s_user_ns;
3043-
if (!kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) ||
3044-
!kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns)))
3039+
if (!fsuidgid_has_mapping(dir->dentry->d_sb, mnt_userns))
30453040
return -EOVERFLOW;
30463041

30473042
error = inode_permission(mnt_userns, dir->dentry->d_inode,

include/linux/fs.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,26 @@ static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns)
16921692
return kgid_from_mnt(mnt_userns, current_fsgid());
16931693
}
16941694

1695+
/**
1696+
* fsuidgid_has_mapping() - check whether caller's fsuid/fsgid is mapped
1697+
* @sb: the superblock we want a mapping in
1698+
* @mnt_userns: user namespace of the relevant mount
1699+
*
1700+
* Check whether the caller's fsuid and fsgid have a valid mapping in the
1701+
* s_user_ns of the superblock @sb. If the caller is on an idmapped mount map
1702+
* the caller's fsuid and fsgid according to the @mnt_userns first.
1703+
*
1704+
* Return: true if fsuid and fsgid is mapped, false if not.
1705+
*/
1706+
static inline bool fsuidgid_has_mapping(struct super_block *sb,
1707+
struct user_namespace *mnt_userns)
1708+
{
1709+
struct user_namespace *s_user_ns = sb->s_user_ns;
1710+
1711+
return kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) &&
1712+
kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns));
1713+
}
1714+
16951715
extern struct timespec64 current_time(struct inode *inode);
16961716

16971717
/*

0 commit comments

Comments
 (0)