fs: tweak fsuidgid_has_mapping()
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 28 Jun 2022 12:16:11 +0000 (14:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 2 Jul 2022 14:41:15 +0000 (16:41 +0200)
commit 476860b3eb4a50958243158861d5340066df5af2 upstream.

If the caller's fs{g,u}id aren't mapped in the mount's idmapping we can
return early and skip the check whether the mapped fs{g,u}id also have a
mapping in the filesystem's idmapping. If the fs{g,u}id aren't mapped in
the mount's idmapping they consequently can't be mapped in the
filesystem's idmapping. So there's no point in checking that.

Link: https://lore.kernel.org/r/20211123114227.3124056-4-brauner@kernel.org
Link: https://lore.kernel.org/r/20211130121032.3753852-4-brauner@kernel.org
Link: https://lore.kernel.org/r/20211203111707.3901969-4-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
CC: linux-fsdevel@vger.kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Seth Forshee <sforshee@digitalocean.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/fs.h

index b1d446d..ffc0655 100644 (file)
@@ -1697,10 +1697,18 @@ static inline void inode_fsgid_set(struct inode *inode,
 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;
+       struct user_namespace *fs_userns = sb->s_user_ns;
+       kuid_t kuid;
+       kgid_t kgid;
 
-       return kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) &&
-              kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns));
+       kuid = mapped_fsuid(mnt_userns);
+       if (!uid_valid(kuid))
+               return false;
+       kgid = mapped_fsgid(mnt_userns);
+       if (!gid_valid(kgid))
+               return false;
+       return kuid_has_mapping(fs_userns, kuid) &&
+              kgid_has_mapping(fs_userns, kgid);
 }
 
 extern struct timespec64 current_time(struct inode *inode);