Skip to content

Commit

Permalink
block: fix use after free in __blkdev_direct_IO
Browse files Browse the repository at this point in the history
We can't dereference the dio structure after submitting the last bio for
this request, as I/O completion might have happened before the code is
run. Introduce a local is_sync variable instead.

Fixes: 542ff7b ("block: new direct I/O implementation")
Signed-off-by: Christoph Hellwig <[email protected]>
Reported-by: Matias Bjørling <[email protected]>
Tested-by: Matias Bjørling <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Christoph Hellwig authored and axboe committed Jan 24, 2017
1 parent a4685d2 commit 690e532
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
struct blk_plug plug;
struct blkdev_dio *dio;
struct bio *bio;
bool is_read = (iov_iter_rw(iter) == READ);
bool is_read = (iov_iter_rw(iter) == READ), is_sync;
loff_t pos = iocb->ki_pos;
blk_qc_t qc = BLK_QC_T_NONE;
int ret;
Expand All @@ -344,7 +344,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
bio_get(bio); /* extra ref for the completion handler */

dio = container_of(bio, struct blkdev_dio, bio);
dio->is_sync = is_sync_kiocb(iocb);
dio->is_sync = is_sync = is_sync_kiocb(iocb);
if (dio->is_sync)
dio->waiter = current;
else
Expand Down Expand Up @@ -398,7 +398,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
}
blk_finish_plug(&plug);

if (!dio->is_sync)
if (!is_sync)
return -EIOCBQUEUED;

for (;;) {
Expand Down

0 comments on commit 690e532

Please sign in to comment.