diff options
-rw-r--r-- | fs/attr.c | 4 | ||||
-rw-r--r-- | fs/ext4/inode.c | 9 | ||||
-rw-r--r-- | fs/f2fs/file.c | 13 | ||||
-rw-r--r-- | fs/quota/dquot.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 4 | ||||
-rw-r--r-- | include/linux/fs.h | 24 | ||||
-rw-r--r-- | include/linux/quotaops.h | 5 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 5 |
8 files changed, 36 insertions, 32 deletions
diff --git a/fs/attr.c b/fs/attr.c index 2cadd055dbf2..bbb9118c6c8b 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -311,8 +311,8 @@ void setattr_copy(struct mnt_idmap *idmap, struct inode *inode, struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); unsigned int ia_valid = attr->ia_valid; - i_uid_update(mnt_userns, attr, inode); - i_gid_update(mnt_userns, attr, inode); + i_uid_update(idmap, attr, inode); + i_gid_update(idmap, attr, inode); if (ia_valid & ATTR_ATIME) inode->i_atime = attr->ia_atime; if (ia_valid & ATTR_MTIME) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8b9b1cb6e3ab..be664dc9b991 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5442,7 +5442,6 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, int orphan = 0; const unsigned int ia_valid = attr->ia_valid; bool inc_ivers = true; - struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) return -EIO; @@ -5473,8 +5472,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, return error; } - if (i_uid_needs_update(mnt_userns, attr, inode) || - i_gid_needs_update(mnt_userns, attr, inode)) { + if (i_uid_needs_update(idmap, attr, inode) || + i_gid_needs_update(idmap, attr, inode)) { handle_t *handle; /* (user+group)*(old+new) structure, inode write (sb, @@ -5500,8 +5499,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, } /* Update corresponding info in inode so that everything is in * one transaction */ - i_uid_update(mnt_userns, attr, inode); - i_gid_update(mnt_userns, attr, inode); + i_uid_update(idmap, attr, inode); + i_gid_update(idmap, attr, inode); error = ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); if (unlikely(error)) { diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 262c831e3450..577c1613b6cf 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -909,8 +909,8 @@ static void __setattr_copy(struct mnt_idmap *idmap, unsigned int ia_valid = attr->ia_valid; struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); - i_uid_update(mnt_userns, attr, inode); - i_gid_update(mnt_userns, attr, inode); + i_uid_update(idmap, attr, inode); + i_gid_update(idmap, attr, inode); if (ia_valid & ATTR_ATIME) inode->i_atime = attr->ia_atime; if (ia_valid & ATTR_MTIME) @@ -934,7 +934,6 @@ static void __setattr_copy(struct mnt_idmap *idmap, int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr) { - struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); struct inode *inode = d_inode(dentry); int err; @@ -970,8 +969,8 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (err) return err; } - if (i_uid_needs_update(mnt_userns, attr, inode) || - i_gid_needs_update(mnt_userns, attr, inode)) { + if (i_uid_needs_update(idmap, attr, inode) || + i_gid_needs_update(idmap, attr, inode)) { f2fs_lock_op(F2FS_I_SB(inode)); err = dquot_transfer(idmap, inode, attr); if (err) { @@ -984,8 +983,8 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, * update uid/gid under lock_op(), so that dquot and inode can * be updated atomically. */ - i_uid_update(mnt_userns, attr, inode); - i_gid_update(mnt_userns, attr, inode); + i_uid_update(idmap, attr, inode); + i_gid_update(idmap, attr, inode); f2fs_mark_inode_dirty_sync(inode, true); f2fs_unlock_op(F2FS_I_SB(inode)); } diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6ae106c0f146..207434a854f3 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2097,7 +2097,7 @@ int dquot_transfer(struct mnt_idmap *idmap, struct inode *inode, if (!dquot_active(inode)) return 0; - if (i_uid_needs_update(mnt_userns, iattr, inode)) { + if (i_uid_needs_update(idmap, iattr, inode)) { kuid_t kuid = from_vfsuid(mnt_userns, i_user_ns(inode), iattr->ia_vfsuid); @@ -2111,7 +2111,7 @@ int dquot_transfer(struct mnt_idmap *idmap, struct inode *inode, } transfer_to[USRQUOTA] = dquot; } - if (i_gid_needs_update(mnt_userns, iattr, inode)) { + if (i_gid_needs_update(idmap, iattr, inode)) { kgid_t kgid = from_vfsgid(mnt_userns, i_user_ns(inode), iattr->ia_vfsgid); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 94c2f4aa675a..c6284fb9e136 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -720,12 +720,12 @@ xfs_setattr_nonsize( * also. */ if (XFS_IS_UQUOTA_ON(mp) && - i_uid_needs_update(mnt_userns, iattr, inode)) { + i_uid_needs_update(idmap, iattr, inode)) { ASSERT(udqp); old_udqp = xfs_qm_vop_chown(tp, ip, &ip->i_udquot, udqp); } if (XFS_IS_GQUOTA_ON(mp) && - i_gid_needs_update(mnt_userns, iattr, inode)) { + i_gid_needs_update(idmap, iattr, inode)) { ASSERT(xfs_has_pquotino(mp) || !XFS_IS_PQUOTA_ON(mp)); ASSERT(gdqp); old_gdqp = xfs_qm_vop_chown(tp, ip, &ip->i_gdquot, gdqp); diff --git a/include/linux/fs.h b/include/linux/fs.h index 696540a86183..3611d459bf88 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1647,7 +1647,7 @@ static inline vfsuid_t i_uid_into_vfsuid(struct user_namespace *mnt_userns, /** * i_uid_needs_update - check whether inode's i_uid needs to be updated - * @mnt_userns: user namespace of the mount the inode was found from + * @idmap: idmap of the mount the inode was found from * @attr: the new attributes of @inode * @inode: the inode to update * @@ -1656,10 +1656,12 @@ static inline vfsuid_t i_uid_into_vfsuid(struct user_namespace *mnt_userns, * * Return: true if @inode's i_uid field needs to be updated, false if not. */ -static inline bool i_uid_needs_update(struct user_namespace *mnt_userns, +static inline bool i_uid_needs_update(struct mnt_idmap *idmap, const struct iattr *attr, const struct inode *inode) { + struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); + return ((attr->ia_valid & ATTR_UID) && !vfsuid_eq(attr->ia_vfsuid, i_uid_into_vfsuid(mnt_userns, inode))); @@ -1667,17 +1669,19 @@ static inline bool i_uid_needs_update(struct user_namespace *mnt_userns, /** * i_uid_update - update @inode's i_uid field - * @mnt_userns: user namespace of the mount the inode was found from + * @idmap: idmap of the mount the inode was found from * @attr: the new attributes of @inode * @inode: the inode to update * * Safely update @inode's i_uid field translating the vfsuid of any idmapped * mount into the filesystem kuid. */ -static inline void i_uid_update(struct user_namespace *mnt_userns, +static inline void i_uid_update(struct mnt_idmap *idmap, const struct iattr *attr, struct inode *inode) { + struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); + if (attr->ia_valid & ATTR_UID) inode->i_uid = from_vfsuid(mnt_userns, i_user_ns(inode), attr->ia_vfsuid); @@ -1699,7 +1703,7 @@ static inline vfsgid_t i_gid_into_vfsgid(struct user_namespace *mnt_userns, /** * i_gid_needs_update - check whether inode's i_gid needs to be updated - * @mnt_userns: user namespace of the mount the inode was found from + * @idmap: idmap of the mount the inode was found from * @attr: the new attributes of @inode * @inode: the inode to update * @@ -1708,10 +1712,12 @@ static inline vfsgid_t i_gid_into_vfsgid(struct user_namespace *mnt_userns, * * Return: true if @inode's i_gid field needs to be updated, false if not. */ -static inline bool i_gid_needs_update(struct user_namespace *mnt_userns, +static inline bool i_gid_needs_update(struct mnt_idmap *idmap, const struct iattr *attr, const struct inode *inode) { + struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); + return ((attr->ia_valid & ATTR_GID) && !vfsgid_eq(attr->ia_vfsgid, i_gid_into_vfsgid(mnt_userns, inode))); @@ -1719,17 +1725,19 @@ static inline bool i_gid_needs_update(struct user_namespace *mnt_userns, /** * i_gid_update - update @inode's i_gid field - * @mnt_userns: user namespace of the mount the inode was found from + * @idmap: idmap of the mount the inode was found from * @attr: the new attributes of @inode * @inode: the inode to update * * Safely update @inode's i_gid field translating the vfsgid of any idmapped * mount into the filesystem kgid. */ -static inline void i_gid_update(struct user_namespace *mnt_userns, +static inline void i_gid_update(struct mnt_idmap *idmap, const struct iattr *attr, struct inode *inode) { + struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); + if (attr->ia_valid & ATTR_GID) inode->i_gid = from_vfsgid(mnt_userns, i_user_ns(inode), attr->ia_vfsgid); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 5f6744b3ceac..11a4becff3a9 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -23,10 +23,9 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb) static inline bool is_quota_modification(struct mnt_idmap *idmap, struct inode *inode, struct iattr *ia) { - struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); return ((ia->ia_valid & ATTR_SIZE) || - i_uid_needs_update(mnt_userns, ia, inode) || - i_gid_needs_update(mnt_userns, ia, inode)); + i_uid_needs_update(idmap, ia, inode) || + i_gid_needs_update(idmap, ia, inode)); } #if defined(CONFIG_QUOTA) diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 4e5adddb3577..cf24c5255583 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -783,11 +783,10 @@ static int evm_attr_change(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_backing_inode(dentry); - struct user_namespace *mnt_userns = mnt_idmap_owner(idmap); unsigned int ia_valid = attr->ia_valid; - if (!i_uid_needs_update(mnt_userns, attr, inode) && - !i_gid_needs_update(mnt_userns, attr, inode) && + if (!i_uid_needs_update(idmap, attr, inode) && + !i_gid_needs_update(idmap, attr, inode) && (!(ia_valid & ATTR_MODE) || attr->ia_mode == inode->i_mode)) return 0; |