Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 690e5325 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: fix use after free in __blkdev_direct_IO



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: 542ff7bf ("block: new direct I/O implementation")
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reported-by: default avatarMatias Bjørling <m@bjorling.me>
Tested-by: default avatarMatias Bjørling <m@bjorling.me>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent a4685d2f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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 (;;) {