[PATCH 2/2] Revert "block: add single bio async direct IO helper"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This reverts commit 54a88eb838d37af930c9f19e1930a4fba6789cb5.

git bisect shows that commit 54a88eb838d3 ("block: add single bio async
direct IO helper") causes the following UAF:

BUG: KASAN: use-after-free in io_submit_one+0x496/0x2fe0 fs/aio.c:1882
Write of size 4 at addr ffff888027c338a0 by task syz-executor873/15100

CPU: 2 PID: 15100 Comm: syz-executor873 Not tainted 5.16.0-rc1-syzk #1
Hardware name: Red Hat KVM, BIOS
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x89/0xb5 lib/dump_stack.c:106
 print_address_description.constprop.9+0x28/0x160 mm/kasan/report.c:247
 __kasan_report mm/kasan/report.c:433 [inline]
 kasan_report.cold.14+0x7d/0x117 mm/kasan/report.c:450
 check_region_inline mm/kasan/generic.c:183 [inline]
 kasan_check_range+0x18e/0x1f0 mm/kasan/generic.c:189
 __kasan_check_write+0x14/0x20 mm/kasan/shadow.c:37
 instrument_atomic_read_write include/linux/instrumented.h:101 [inline]
 atomic_fetch_sub_release
    include/linux/atomic/atomic-instrumented.h:167 [inline]
 __refcount_sub_and_test include/linux/refcount.h:272 [inline]
 __refcount_dec_and_test include/linux/refcount.h:315 [inline]
 refcount_dec_and_test include/linux/refcount.h:333 [inline]
 iocb_put fs/aio.c:1161 [inline]
 io_submit_one+0x496/0x2fe0 fs/aio.c:1882
 __do_sys_io_submit fs/aio.c:1938 [inline]
__se_sys_io_submit fs/aio.c:1908 [inline]
 __x64_sys_io_submit+0x1c7/0x4a0 fs/aio.c:1908
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x3a/0x80 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x44/0xae

Conflicts:
	block/fops.c

Reported-by: syzkaller <syzkaller@xxxxxxxxxxxxxxxx>
Signed-off-by: George Kennedy <george.kennedy@xxxxxxxxxx>
---
 block/fops.c | 86 +++---------------------------------------------------------
 1 file changed, 3 insertions(+), 83 deletions(-)

diff --git a/block/fops.c b/block/fops.c
index e73167b..88e0401 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -282,84 +282,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 	return ret;
 }
 
-static void blkdev_bio_end_io_async(struct bio *bio)
-{
-	struct blkdev_dio *dio = container_of(bio, struct blkdev_dio, bio);
-	struct kiocb *iocb = dio->iocb;
-	ssize_t ret;
-
-	if (likely(!bio->bi_status)) {
-		ret = dio->size;
-		iocb->ki_pos += ret;
-	} else {
-		ret = blk_status_to_errno(bio->bi_status);
-	}
-
-	iocb->ki_complete(iocb, ret);
-
-	if (dio->flags & DIO_SHOULD_DIRTY) {
-		bio_check_pages_dirty(bio);
-	} else {
-		bio_release_pages(bio, false);
-		bio_put(bio);
-	}
-}
-
-static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb,
-					struct iov_iter *iter,
-					unsigned int nr_pages)
-{
-	struct block_device *bdev = iocb->ki_filp->private_data;
-	struct blkdev_dio *dio;
-	struct bio *bio;
-	loff_t pos = iocb->ki_pos;
-	int ret = 0;
-
-	if ((pos | iov_iter_alignment(iter)) &
-	    (bdev_logical_block_size(bdev) - 1))
-		return -EINVAL;
-
-	bio = bio_alloc_kiocb(iocb, nr_pages, &blkdev_dio_pool);
-	dio = container_of(bio, struct blkdev_dio, bio);
-	dio->flags = 0;
-	dio->iocb = iocb;
-	bio_set_dev(bio, bdev);
-	bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT;
-	bio->bi_write_hint = iocb->ki_hint;
-	bio->bi_end_io = blkdev_bio_end_io_async;
-	bio->bi_ioprio = iocb->ki_ioprio;
-
-	ret = bio_iov_iter_get_pages(bio, iter);
-	if (unlikely(ret)) {
-		bio->bi_status = BLK_STS_IOERR;
-		bio_endio(bio);
-		return ret;
-	}
-	dio->size = bio->bi_iter.bi_size;
-
-	if (iov_iter_rw(iter) == READ) {
-		bio->bi_opf = REQ_OP_READ;
-		if (iter_is_iovec(iter)) {
-			dio->flags |= DIO_SHOULD_DIRTY;
-			bio_set_pages_dirty(bio);
-		}
-	} else {
-		bio->bi_opf = dio_bio_write_op(iocb);
-		task_io_account_write(bio->bi_iter.bi_size);
-	}
-
-	if (iocb->ki_flags & IOCB_HIPRI) {
-		bio->bi_opf |= REQ_POLLED | REQ_NOWAIT;
-		submit_bio(bio);
-		WRITE_ONCE(iocb->private, bio);
-	} else {
-		if (iocb->ki_flags & IOCB_NOWAIT)
-			bio->bi_opf |= REQ_NOWAIT;
-		submit_bio(bio);
-	}
-	return -EIOCBQUEUED;
-}
-
 static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 {
 	unsigned int nr_pages;
@@ -368,11 +290,9 @@ static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 		return 0;
 
 	nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1);
-	if (likely(nr_pages <= BIO_MAX_VECS)) {
-		if (is_sync_kiocb(iocb))
-			return __blkdev_direct_IO_simple(iocb, iter, nr_pages);
-		return __blkdev_direct_IO_async(iocb, iter, nr_pages);
-	}
+	if (is_sync_kiocb(iocb) && nr_pages <= BIO_MAX_VECS)
+		return __blkdev_direct_IO_simple(iocb, iter, nr_pages);
+
 	return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages));
 }
 
-- 
1.8.3.1




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux