Unverified Commit 8e538913 authored by Christian Brauner's avatar Christian Brauner
Browse files

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: default avatarVivek 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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
parent a65e58e7
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -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,
+20 −0
Original line number Diff line number Diff line
@@ -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);

/*