aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2014-10-01 19:04:11 -0400
committerDave Chinner <david@fromorbit.com>2014-10-01 19:04:11 -0400
commite11bb8052c3f500e66142f33579cc054d691a8fb (patch)
treea0a569a145631d37bd629a9c8a156e49515de626 /fs/xfs
parentcf53e99d192171a58791136d33fd3fea5d8bab35 (diff)
xfs: synchronous buffer IO needs a reference
When synchronous IO runs IO completion work, it does so without an IO reference or a hold reference on the buffer. The IO "hold reference" is owned by the submitter, and released when the submission is complete. The IO reference is released when both the submitter and the bio end_io processing is run, and so if the io completion work is run from IO completion context, it is run without an IO reference. Hence we can get the situation where the submitter can submit the IO, see an error on the buffer and unlock and free the buffer while there is still IO in progress. This leads to use-after-free and memory corruption. Fix this by taking a "sync IO hold" reference that is owned by the IO and not released until after the buffer completion calls are run to wake up synchronous waiters. This means that the buffer will not be freed in any circumstance until all IO processing is completed. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_buf.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 9dc4c2223035..48b1e2989ea4 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1019,6 +1019,9 @@ xfs_buf_iodone_work(
1019 else { 1019 else {
1020 ASSERT(read && bp->b_ops); 1020 ASSERT(read && bp->b_ops);
1021 complete(&bp->b_iowait); 1021 complete(&bp->b_iowait);
1022
1023 /* release the !XBF_ASYNC ref now we are done. */
1024 xfs_buf_rele(bp);
1022 } 1025 }
1023} 1026}
1024 1027
@@ -1044,6 +1047,7 @@ xfs_buf_ioend(
1044 } else { 1047 } else {
1045 bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); 1048 bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD);
1046 complete(&bp->b_iowait); 1049 complete(&bp->b_iowait);
1050 xfs_buf_rele(bp);
1047 } 1051 }
1048} 1052}
1049 1053
@@ -1086,8 +1090,11 @@ xfs_bioerror(
1086 xfs_buf_ioerror(bp, -EIO); 1090 xfs_buf_ioerror(bp, -EIO);
1087 1091
1088 /* 1092 /*
1089 * We're calling xfs_buf_ioend, so delete XBF_DONE flag. 1093 * We're calling xfs_buf_ioend, so delete XBF_DONE flag. For
1094 * sync IO, xfs_buf_ioend is going to remove a ref here.
1090 */ 1095 */
1096 if (!(bp->b_flags & XBF_ASYNC))
1097 xfs_buf_hold(bp);
1091 XFS_BUF_UNREAD(bp); 1098 XFS_BUF_UNREAD(bp);
1092 XFS_BUF_UNDONE(bp); 1099 XFS_BUF_UNDONE(bp);
1093 xfs_buf_stale(bp); 1100 xfs_buf_stale(bp);
@@ -1383,22 +1390,48 @@ xfs_buf_iorequest(
1383 1390
1384 if (bp->b_flags & XBF_WRITE) 1391 if (bp->b_flags & XBF_WRITE)
1385 xfs_buf_wait_unpin(bp); 1392 xfs_buf_wait_unpin(bp);
1393
1394 /*
1395 * Take references to the buffer. For XBF_ASYNC buffers, holding a
1396 * reference for as long as submission takes is all that is necessary
1397 * here. The IO inherits the lock and hold count from the submitter,
1398 * and these are release during IO completion processing. Taking a hold
1399 * over submission ensures that the buffer is not freed until we have
1400 * completed all processing, regardless of when IO errors occur or are
1401 * reported.
1402 *
1403 * However, for synchronous IO, the IO does not inherit the submitters
1404 * reference count, nor the buffer lock. Hence we need to take an extra
1405 * reference to the buffer for the for the IO context so that we can
1406 * guarantee the buffer is not freed until all IO completion processing
1407 * is done. Otherwise the caller can drop their reference while the IO
1408 * is still in progress and hence trigger a use-after-free situation.
1409 */
1386 xfs_buf_hold(bp); 1410 xfs_buf_hold(bp);
1411 if (!(bp->b_flags & XBF_ASYNC))
1412 xfs_buf_hold(bp);
1413
1387 1414
1388 /* 1415 /*
1389 * Set the count to 1 initially, this will stop an I/O 1416 * Set the count to 1 initially, this will stop an I/O completion
1390 * completion callout which happens before we have started 1417 * callout which happens before we have started all the I/O from calling
1391 * all the I/O from calling xfs_buf_ioend too early. 1418 * xfs_buf_ioend too early.
1392 */ 1419 */
1393 atomic_set(&bp->b_io_remaining, 1); 1420 atomic_set(&bp->b_io_remaining, 1);
1394 _xfs_buf_ioapply(bp); 1421 _xfs_buf_ioapply(bp);
1422
1395 /* 1423 /*
1396 * If _xfs_buf_ioapply failed, we'll get back here with 1424 * If _xfs_buf_ioapply failed or we are doing synchronous IO that
1397 * only the reference we took above. _xfs_buf_ioend will 1425 * completes extremely quickly, we can get back here with only the IO
1398 * drop it to zero, so we'd better not queue it for later, 1426 * reference we took above. _xfs_buf_ioend will drop it to zero. Run
1399 * or we'll free it before it's done. 1427 * completion processing synchronously so that we don't return to the
1428 * caller with completion still pending. This avoids unnecessary context
1429 * switches associated with the end_io workqueue.
1400 */ 1430 */
1401 _xfs_buf_ioend(bp, bp->b_error ? 0 : 1); 1431 if (bp->b_error || !(bp->b_flags & XBF_ASYNC))
1432 _xfs_buf_ioend(bp, 0);
1433 else
1434 _xfs_buf_ioend(bp, 1);
1402 1435
1403 xfs_buf_rele(bp); 1436 xfs_buf_rele(bp);
1404} 1437}