diff options
author | David Chinner <dgc@sgi.com> | 2007-02-10 18:36:04 +1100 |
---|---|---|
committer | Tim Shimmin <tes@sgi.com> | 2007-02-10 18:36:04 +1100 |
commit | f74eaf59b36c0ad01f416b567f89c737bbf82bae (patch) | |
tree | 2420bc97336a79b317b461cb7ece9f5bc40d8aec /fs | |
parent | e5889e90dda328443161e9512f1123c9814d03de (diff) | |
download | op-kernel-dev-f74eaf59b36c0ad01f416b567f89c737bbf82bae.zip op-kernel-dev-f74eaf59b36c0ad01f416b567f89c737bbf82bae.tar.gz |
[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.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index cd51858..e42418f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2707,10 +2707,24 @@ xfs_idestroy( ktrace_free(ip->i_dir_trace); #endif if (ip->i_itemp) { - /* XXXdpd should be able to assert this but shutdown - * is leaving the AIL behind. */ - ASSERT(((ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL) == 0) || - XFS_FORCED_SHUTDOWN(ip->i_mount)); + /* + * Only if we are shutting down the fs will we see an + * inode still in the AIL. If it is there, we should remove + * it to prevent a use-after-free from occurring. + */ + xfs_mount_t *mp = ip->i_mount; + xfs_log_item_t *lip = &ip->i_itemp->ili_item; + int s; + + ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || + XFS_FORCED_SHUTDOWN(ip->i_mount)); + if (lip->li_flags & XFS_LI_IN_AIL) { + AIL_LOCK(mp, s); + if (lip->li_flags & XFS_LI_IN_AIL) + xfs_trans_delete_ail(mp, lip, s); + else + AIL_UNLOCK(mp, s); + } xfs_inode_item_destroy(ip); } kmem_zone_free(xfs_inode_zone, ip); |