summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_health.c8
-rw-r--r--fs/xfs/xfs_icache.c9
2 files changed, 14 insertions, 3 deletions
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);