xfs: use reference counts to free clean buffer items
authorDave Chinner <dchinner@redhat.com>
Mon, 12 Aug 2013 10:50:11 +0000 (20:50 +1000)
committerBen Myers <bpm@sgi.com>
Thu, 15 Aug 2013 21:42:29 +0000 (16:42 -0500)
When a transaction is cancelled and the buffer log item is clean in
the transaction, the buffer log item is unconditionally freed. If
the log item is in the AIL, however, this leads to a use after free
condition as the item still has other users.

In this case, xfs_buf_item_relse() should only be called on clean
buffer items if the reference count has dropped to zero. This
ensures only the last user frees the item.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
fs/xfs/xfs_buf_item.c

index 9358504e4b688fbdb272a7c12617540746488dc7..3a944b198e35a0fbfc758a84fd39a2e0674d360f 100644 (file)
@@ -613,11 +613,9 @@ xfs_buf_item_unlock(
                        }
                }
        }
-       if (clean)
-               xfs_buf_item_relse(bp);
-       else if (aborted) {
+       if (clean || aborted) {
                if (atomic_dec_and_test(&bip->bli_refcount)) {
-                       ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp));
+                       ASSERT(!aborted || XFS_FORCED_SHUTDOWN(lip->li_mountp));
                        xfs_buf_item_relse(bp);
                }
        } else