fs: use type safe idmapping helpers
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>
This commit is contained in:
Родитель
9c4f28ddfb
Коммит
a2bd096fb2
|
@ -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;
|
||||
|
|
16
fs/exec.c
16
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
40
fs/namei.c
40
fs/namei.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -44,12 +44,15 @@
|
|||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче