raid10: cleanup memleak at raid10_make_request
authorNigel Croxon <ncroxon@redhat.com>
Thu, 3 Jul 2025 15:23:04 +0000 (11:23 -0400)
committerYu Kuai <yukuai3@huawei.com>
Sat, 5 Jul 2025 11:30:41 +0000 (19:30 +0800)
If raid10_read_request or raid10_write_request registers a new
request and the REQ_NOWAIT flag is set, the code does not
free the malloc from the mempool.

unreferenced object 0xffff8884802c3200 (size 192):
   comm "fio", pid 9197, jiffies 4298078271
   hex dump (first 32 bytes):
     00 00 00 00 00 00 00 00 88 41 02 00 00 00 00 00  .........A......
     08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   backtrace (crc c1a049a2):
     __kmalloc+0x2bb/0x450
     mempool_alloc+0x11b/0x320
     raid10_make_request+0x19e/0x650 [raid10]
     md_handle_request+0x3b3/0x9e0
     __submit_bio+0x394/0x560
     __submit_bio_noacct+0x145/0x530
     submit_bio_noacct_nocheck+0x682/0x830
     __blkdev_direct_IO_async+0x4dc/0x6b0
     blkdev_read_iter+0x1e5/0x3b0
     __io_read+0x230/0x1110
     io_read+0x13/0x30
     io_issue_sqe+0x134/0x1180
     io_submit_sqes+0x48c/0xe90
     __do_sys_io_uring_enter+0x574/0x8b0
     do_syscall_64+0x5c/0xe0
     entry_SYSCALL_64_after_hwframe+0x76/0x7e

V4: changing backing tree to see if CKI tests will pass.
The patch code has not changed between any versions.

Fixes: c9aa889b035f ("md: raid10 add nowait support")
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
Link: https://lore.kernel.org/linux-raid/c0787379-9caa-42f3-b5fc-369aed784400@redhat.com
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
drivers/md/raid10.c

index b74780af4c220db77d1c3d502366faed9fb71590..917055dc01eddc74c316382bd435af00a801dcab 100644 (file)
@@ -1182,8 +1182,11 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
                }
        }
 
-       if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors))
+       if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors)) {
+               raid_end_bio_io(r10_bio);
                return;
+       }
+
        rdev = read_balance(conf, r10_bio, &max_sectors);
        if (!rdev) {
                if (err_rdev) {
@@ -1370,8 +1373,11 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
        }
 
        sectors = r10_bio->sectors;
-       if (!regular_request_wait(mddev, conf, bio, sectors))
+       if (!regular_request_wait(mddev, conf, bio, sectors)) {
+               raid_end_bio_io(r10_bio);
                return;
+       }
+
        if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
            (mddev->reshape_backwards
             ? (bio->bi_iter.bi_sector < conf->reshape_safe &&