diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 6475159eb930..239b843e83d4 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -316,8 +316,12 @@ xfs_rgno_mark_sick( static inline void xfs_inode_report_fserror(struct xfs_inode *ip) { - /* Report metadata inodes as general filesystem corruption */ - if (xfs_is_internal_inode(ip)) { + /* + * Do not report inodes being constructed or freed, or metadata inodes, + * to fsnotify. + */ + if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIM) || + xfs_is_internal_inode(ip)) { fserror_report_metadata(ip->i_mount->m_super, -EFSCORRUPTED, GFP_NOFS); return; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index f2d4294efd37..a7a09e7eec81 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -639,6 +639,14 @@ xfs_iget_cache_miss( if (!ip) return -ENOMEM; + /* + * Set XFS_INEW as early as possible so that the health code won't pass + * the inode to the fserror code if the ondisk inode cannot be loaded. + * We're going to free the xfs_inode immediately if that happens, which + * would lead to UAF problems. + */ + xfs_iflags_set(ip, XFS_INEW); + error = xfs_imap(pag, tp, ip->i_ino, &ip->i_imap, flags); if (error) goto out_destroy; @@ -716,7 +724,6 @@ xfs_iget_cache_miss( ip->i_udquot = NULL; ip->i_gdquot = NULL; ip->i_pdquot = NULL; - xfs_iflags_set(ip, XFS_INEW); /* insert the new inode */ spin_lock(&pag->pag_ici_lock);