fs: use type safe idmapping helpers
authorChristian Brauner <brauner@kernel.org>
Wed, 22 Jun 2022 20:12:16 +0000 (22:12 +0200)
committerChristian Brauner (Microsoft) <brauner@kernel.org>
Wed, 26 Oct 2022 08:02:34 +0000 (10:02 +0200)
We already ported most parts and filesystems over for v6.0 to the new
vfs{g,u}id_t type and associated helpers for v6.0. Convert the remaining
places so we can remove all the old helpers.
This is a non-functional change.

Reviewed-by: Seth Forshee (DigitalOcean) <sforshee@kernel.org>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
fs/coredump.c
fs/exec.c
fs/inode.c
fs/namei.c
fs/remap_range.c
fs/stat.c

index 7bad778..a133103 100644 (file)
@@ -716,8 +716,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
                 * filesystem.
                 */
                mnt_userns = file_mnt_user_ns(cprm.file);
-               if (!uid_eq(i_uid_into_mnt(mnt_userns, inode),
-                           current_fsuid())) {
+               if (!vfsuid_eq_kuid(i_uid_into_vfsuid(mnt_userns, inode),
+                                   current_fsuid())) {
                        pr_info_ratelimited("Core dump to %s aborted: cannot preserve file owner\n",
                                            cn.corename);
                        goto close_fail;
index 349a5da..dd91ade 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1591,8 +1591,8 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
        struct user_namespace *mnt_userns;
        struct inode *inode = file_inode(file);
        unsigned int mode;
-       kuid_t uid;
-       kgid_t gid;
+       vfsuid_t vfsuid;
+       vfsgid_t vfsgid;
 
        if (!mnt_may_suid(file->f_path.mnt))
                return;
@@ -1611,23 +1611,23 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
 
        /* reload atomically mode/uid/gid now that lock held */
        mode = inode->i_mode;
-       uid = i_uid_into_mnt(mnt_userns, inode);
-       gid = i_gid_into_mnt(mnt_userns, inode);
+       vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
+       vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
        inode_unlock(inode);
 
        /* We ignore suid/sgid if there are no mappings for them in the ns */
-       if (!kuid_has_mapping(bprm->cred->user_ns, uid) ||
-                !kgid_has_mapping(bprm->cred->user_ns, gid))
+       if (!vfsuid_has_mapping(bprm->cred->user_ns, vfsuid) ||
+           !vfsgid_has_mapping(bprm->cred->user_ns, vfsgid))
                return;
 
        if (mode & S_ISUID) {
                bprm->per_clear |= PER_CLEAR_ON_SETID;
-               bprm->cred->euid = uid;
+               bprm->cred->euid = vfsuid_into_kuid(vfsuid);
        }
 
        if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
                bprm->per_clear |= PER_CLEAR_ON_SETID;
-               bprm->cred->egid = gid;
+               bprm->cred->egid = vfsgid_into_kgid(vfsgid);
        }
 }
 
index 8c40788..757cac2 100644 (file)
@@ -2326,15 +2326,15 @@ EXPORT_SYMBOL(inode_init_owner);
 bool inode_owner_or_capable(struct user_namespace *mnt_userns,
                            const struct inode *inode)
 {
-       kuid_t i_uid;
+       vfsuid_t vfsuid;
        struct user_namespace *ns;
 
-       i_uid = i_uid_into_mnt(mnt_userns, inode);
-       if (uid_eq(current_fsuid(), i_uid))
+       vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
+       if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
                return true;
 
        ns = current_user_ns();
-       if (kuid_has_mapping(ns, i_uid) && ns_capable(ns, CAP_FOWNER))
+       if (vfsuid_has_mapping(ns, vfsuid) && ns_capable(ns, CAP_FOWNER))
                return true;
        return false;
 }
index 578c211..d5c5cb7 100644 (file)
@@ -336,11 +336,11 @@ static int acl_permission_check(struct user_namespace *mnt_userns,
                                struct inode *inode, int mask)
 {
        unsigned int mode = inode->i_mode;
-       kuid_t i_uid;
+       vfsuid_t vfsuid;
 
        /* Are we the owner? If so, ACL's don't matter */
-       i_uid = i_uid_into_mnt(mnt_userns, inode);
-       if (likely(uid_eq(current_fsuid(), i_uid))) {
+       vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
+       if (likely(vfsuid_eq_kuid(vfsuid, current_fsuid()))) {
                mask &= 7;
                mode >>= 6;
                return (mask & ~mode) ? -EACCES : 0;
@@ -362,8 +362,8 @@ static int acl_permission_check(struct user_namespace *mnt_userns,
         * about? Need to check group ownership if so.
         */
        if (mask & (mode ^ (mode >> 3))) {
-               kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
-               if (in_group_p(kgid))
+               vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
+               if (vfsgid_in_group_p(vfsgid))
                        mode >>= 3;
        }
 
@@ -581,7 +581,7 @@ struct nameidata {
        struct nameidata *saved;
        unsigned        root_seq;
        int             dfd;
-       kuid_t          dir_uid;
+       vfsuid_t        dir_vfsuid;
        umode_t         dir_mode;
 } __randomize_layout;
 
@@ -1095,15 +1095,15 @@ fs_initcall(init_fs_namei_sysctls);
 static inline int may_follow_link(struct nameidata *nd, const struct inode *inode)
 {
        struct user_namespace *mnt_userns;
-       kuid_t i_uid;
+       vfsuid_t vfsuid;
 
        if (!sysctl_protected_symlinks)
                return 0;
 
        mnt_userns = mnt_user_ns(nd->path.mnt);
-       i_uid = i_uid_into_mnt(mnt_userns, inode);
+       vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
        /* Allowed if owner and follower match. */
-       if (uid_eq(current_cred()->fsuid, i_uid))
+       if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
                return 0;
 
        /* Allowed if parent directory not sticky and world-writable. */
@@ -1111,7 +1111,7 @@ static inline int may_follow_link(struct nameidata *nd, const struct inode *inod
                return 0;
 
        /* Allowed if parent directory and link owner match. */
-       if (uid_valid(nd->dir_uid) && uid_eq(nd->dir_uid, i_uid))
+       if (vfsuid_valid(nd->dir_vfsuid) && vfsuid_eq(nd->dir_vfsuid, vfsuid))
                return 0;
 
        if (nd->flags & LOOKUP_RCU)
@@ -1183,8 +1183,8 @@ int may_linkat(struct user_namespace *mnt_userns, const struct path *link)
        struct inode *inode = link->dentry->d_inode;
 
        /* Inode writeback is not safe when the uid or gid are invalid. */
-       if (!uid_valid(i_uid_into_mnt(mnt_userns, inode)) ||
-           !gid_valid(i_gid_into_mnt(mnt_userns, inode)))
+       if (!vfsuid_valid(i_uid_into_vfsuid(mnt_userns, inode)) ||
+           !vfsgid_valid(i_gid_into_vfsgid(mnt_userns, inode)))
                return -EOVERFLOW;
 
        if (!sysctl_protected_hardlinks)
@@ -1232,13 +1232,13 @@ static int may_create_in_sticky(struct user_namespace *mnt_userns,
                                struct nameidata *nd, struct inode *const inode)
 {
        umode_t dir_mode = nd->dir_mode;
-       kuid_t dir_uid = nd->dir_uid;
+       vfsuid_t dir_vfsuid = nd->dir_vfsuid;
 
        if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
            (!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
            likely(!(dir_mode & S_ISVTX)) ||
-           uid_eq(i_uid_into_mnt(mnt_userns, inode), dir_uid) ||
-           uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)))
+           vfsuid_eq(i_uid_into_vfsuid(mnt_userns, inode), dir_vfsuid) ||
+           vfsuid_eq_kuid(i_uid_into_vfsuid(mnt_userns, inode), current_fsuid()))
                return 0;
 
        if (likely(dir_mode & 0002) ||
@@ -2307,7 +2307,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 OK:
                        /* pathname or trailing symlink, done */
                        if (!depth) {
-                               nd->dir_uid = i_uid_into_mnt(mnt_userns, nd->inode);
+                               nd->dir_vfsuid = i_uid_into_vfsuid(mnt_userns, nd->inode);
                                nd->dir_mode = nd->inode->i_mode;
                                nd->flags &= ~LOOKUP_PARENT;
                                return 0;
@@ -2885,9 +2885,9 @@ int __check_sticky(struct user_namespace *mnt_userns, struct inode *dir,
 {
        kuid_t fsuid = current_fsuid();
 
-       if (uid_eq(i_uid_into_mnt(mnt_userns, inode), fsuid))
+       if (vfsuid_eq_kuid(i_uid_into_vfsuid(mnt_userns, inode), fsuid))
                return 0;
-       if (uid_eq(i_uid_into_mnt(mnt_userns, dir), fsuid))
+       if (vfsuid_eq_kuid(i_uid_into_vfsuid(mnt_userns, dir), fsuid))
                return 0;
        return !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FOWNER);
 }
@@ -2926,8 +2926,8 @@ static int may_delete(struct user_namespace *mnt_userns, struct inode *dir,
        BUG_ON(victim->d_parent->d_inode != dir);
 
        /* Inode writeback is not safe when the uid or gid are invalid. */
-       if (!uid_valid(i_uid_into_mnt(mnt_userns, inode)) ||
-           !gid_valid(i_gid_into_mnt(mnt_userns, inode)))
+       if (!vfsuid_valid(i_uid_into_vfsuid(mnt_userns, inode)) ||
+           !vfsgid_valid(i_gid_into_vfsgid(mnt_userns, inode)))
                return -EOVERFLOW;
 
        audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
index 654912d..290743c 100644 (file)
@@ -429,7 +429,7 @@ static bool allow_file_dedupe(struct file *file)
                return true;
        if (file->f_mode & FMODE_WRITE)
                return true;
-       if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)))
+       if (vfsuid_eq_kuid(i_uid_into_vfsuid(mnt_userns, inode), current_fsuid()))
                return true;
        if (!inode_permission(mnt_userns, inode, MAY_WRITE))
                return true;
index ef50573..d6cc74c 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
 void generic_fillattr(struct user_namespace *mnt_userns, struct inode *inode,
                      struct kstat *stat)
 {
+       vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_userns, inode);
+       vfsgid_t vfsgid = i_gid_into_vfsgid(mnt_userns, inode);
+
        stat->dev = inode->i_sb->s_dev;
        stat->ino = inode->i_ino;
        stat->mode = inode->i_mode;
        stat->nlink = inode->i_nlink;
-       stat->uid = i_uid_into_mnt(mnt_userns, inode);
-       stat->gid = i_gid_into_mnt(mnt_userns, inode);
+       stat->uid = vfsuid_into_kuid(vfsuid);
+       stat->gid = vfsgid_into_kgid(vfsgid);
        stat->rdev = inode->i_rdev;
        stat->size = i_size_read(inode);
        stat->atime = inode->i_atime;