xfs: buffer pins need to hold a buffer reference
authorDave Chinner <dchinner@redhat.com>
Sun, 4 Jun 2023 18:05:27 +0000 (04:05 +1000)
committerDave Chinner <david@fromorbit.com>
Sun, 4 Jun 2023 18:05:27 +0000 (04:05 +1000)
commit89a4bf0dc3857569a77061d3d5ea2ac85f7e13c6
tree3b7c593d83006e270db119dc0b4ffc261c284f19
parent9561de3a55bed6bdd44a12820ba81ec416e705a7
xfs: buffer pins need to hold a buffer reference

When a buffer is unpinned by xfs_buf_item_unpin(), we need to access
the buffer after we've dropped the buffer log item reference count.
This opens a window where we can have two racing unpins for the
buffer item (e.g. shutdown checkpoint context callback processing
racing with journal IO iclog completion processing) and both attempt
to access the buffer after dropping the BLI reference count.  If we
are unlucky, the "BLI freed" context wins the race and frees the
buffer before the "BLI still active" case checks the buffer pin
count.

This results in a use after free that can only be triggered
in active filesystem shutdown situations.

To fix this, we need to ensure that buffer existence extends beyond
the BLI reference count checks and until the unpin processing is
complete. This implies that a buffer pin operation must also take a
buffer reference to ensure that the buffer cannot be freed until the
buffer unpin processing is complete.

Reported-by: yangerkun <yangerkun@huawei.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_buf_item.c