lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue,  7 Dec 2021 10:51:42 -0500
From:   George Kennedy <george.kennedy@...cle.com>
To:     gregkh@...uxfoundation.org, axboe@...nel.dk, asml.silence@...il.com
Cc:     george.kennedy@...cle.com, linux-block@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: [PATCH 2/2] Revert "block: add single bio async direct IO helper"

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@...glegroups.com>
Signed-off-by: George Kennedy <george.kennedy@...cle.com>
---
 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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ