lkml.org 
[lkml]   [2021]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2/2] Revert "block: add single bio async direct IO helper"
Date
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@googlegroups.com>
Signed-off-by: George Kennedy <george.kennedy@oracle.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
\
 
 \ /
  Last update: 2021-12-07 16:54    [W:0.071 / U:0.040 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site