aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-02-10 02:36:04 -0500
committerTim Shimmin <tes@sgi.com>2007-02-10 02:36:04 -0500
commitf74eaf59b36c0ad01f416b567f89c737bbf82bae (patch)
tree2420bc97336a79b317b461cb7ece9f5bc40d8aec /fs
parente5889e90dda328443161e9512f1123c9814d03de (diff)
[XFS] Fix inode log item use-after-free on forced shutdown
SGI-PV: 959388 SGI-Modid: xfs-linux-melb:xfs-kern:27805a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index cd518581a3bb..e42418f92215 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2707,10 +2707,24 @@ xfs_idestroy(
2707 ktrace_free(ip->i_dir_trace); 2707 ktrace_free(ip->i_dir_trace);
2708#endif 2708#endif
2709 if (ip->i_itemp) { 2709 if (ip->i_itemp) {
2710 /* XXXdpd should be able to assert this but shutdown 2710 /*
2711 * is leaving the AIL behind. */ 2711 * Only if we are shutting down the fs will we see an
2712 ASSERT(((ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL) == 0) || 2712 * inode still in the AIL. If it is there, we should remove
2713 XFS_FORCED_SHUTDOWN(ip->i_mount)); 2713 * it to prevent a use-after-free from occurring.
2714 */
2715 xfs_mount_t *mp = ip->i_mount;
2716 xfs_log_item_t *lip = &ip->i_itemp->ili_item;
2717 int s;
2718
2719 ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
2720 XFS_FORCED_SHUTDOWN(ip->i_mount));
2721 if (lip->li_flags & XFS_LI_IN_AIL) {
2722 AIL_LOCK(mp, s);
2723 if (lip->li_flags & XFS_LI_IN_AIL)
2724 xfs_trans_delete_ail(mp, lip, s);
2725 else
2726 AIL_UNLOCK(mp, s);
2727 }
2714 xfs_inode_item_destroy(ip); 2728 xfs_inode_item_destroy(ip);
2715 } 2729 }
2716 kmem_zone_free(xfs_inode_zone, ip); 2730 kmem_zone_free(xfs_inode_zone, ip);