Skip to content

Commit 58829e4

Browse files
David Chinnernatoscott
authored andcommitted
[XFS] Fix an inode use-after-free durin an unpin. When reclaiming inodes
that have been unlinked, we may need to execute transactions during reclaim. By the time the transaction has hit the disk, the linux inode and xfs vnode may already have been freed so we can't reference them safely. Use the known xfs inode state to determine if it is safe to reference the vnode and linux inode during the unpin operation. SGI-PV: 946321 SGI-Modid: xfs-linux-melb:xfs-kern:25687a Signed-off-by: David Chinner <[email protected]> Signed-off-by: Nathan Scott <[email protected]>
1 parent 1fc5d95 commit 58829e4

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

fs/xfs/xfs_inode.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,16 +2732,29 @@ xfs_iunpin(
27322732
ASSERT(atomic_read(&ip->i_pincount) > 0);
27332733

27342734
if (atomic_dec_and_test(&ip->i_pincount)) {
2735-
vnode_t *vp = XFS_ITOV_NULL(ip);
2735+
/*
2736+
* If the inode is currently being reclaimed, the
2737+
* linux inode _and_ the xfs vnode may have been
2738+
* freed so we cannot reference either of them safely.
2739+
* Hence we should not try to do anything to them
2740+
* if the xfs inode is currently in the reclaim
2741+
* path.
2742+
*
2743+
* However, we still need to issue the unpin wakeup
2744+
* call as the inode reclaim may be blocked waiting for
2745+
* the inode to become unpinned.
2746+
*/
2747+
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
2748+
vnode_t *vp = XFS_ITOV_NULL(ip);
27362749

2737-
/* make sync come back and flush this inode */
2738-
if (vp) {
2739-
struct inode *inode = vn_to_inode(vp);
2750+
/* make sync come back and flush this inode */
2751+
if (vp) {
2752+
struct inode *inode = vn_to_inode(vp);
27402753

2741-
if (!(inode->i_state & I_NEW))
2742-
mark_inode_dirty_sync(inode);
2754+
if (!(inode->i_state & I_NEW))
2755+
mark_inode_dirty_sync(inode);
2756+
}
27432757
}
2744-
27452758
wake_up(&ip->i_ipin_wait);
27462759
}
27472760
}

0 commit comments

Comments
 (0)