Re: [PATCH] md/raid1: prevent a race between write and stop request

Abd-Alrhman Masalkhi <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.raid
Message-ID <[email protected]>
Hi Edward,

On Fri, Aug 28, 2026 at 18:39 +0800, Edward Adam Davis wrote:
> A race condition exists between write and stop requests, leading to a
> null-ptr-deref in [1].
>
> CPU0				CPU1
> ====				====
> md_submit_bio()
> md_handle_request()		do_md_stop()__md_stop()

do_md_stop() must never execute while the array device file is open.
take a look if this rule is not meet.

> raid1_make_request()		 __md_stop()
> raid1_write_request()		   mddev->private = NULL
> wait_barrier()
> conf->nr_pending //trigger [1]
>
> The intervention of a stop request causes inconsistencies in the state
> of mddev members (such as private and pers) while a write request is
> executing; the mddev lock is used to synchronize write and stop requests,
> thereby ensuring consistent mddev state throughout the execution of the
> write request.
>
> Additionally, when a write operation reaches the RAID1 layer, if a stop
> request acquires the mddev lock first and releases mddev->private, the
> bio is terminated and the write request exits.
> 	
> [1]
> KASAN: null-ptr-deref in range [0x0000000000000120-0x0000000000000127]
> RIP: 0010:_wait_barrier+0x8d/0x700 drivers/md/raid1.c:1066
> Call Trace:
>  wait_barrier drivers/md/raid1.c:1154 [inline]
>  raid1_write_request drivers/md/raid1.c:1506 [inline]
>  raid1_make_request+0x484/0x31a0 drivers/md/raid1.c:1696
>  md_handle_request+0x824/0x1230 drivers/md/md.c:417
>  md_submit_bio+0x1e9/0x350 drivers/md/md.c:458
>  __submit_bio block/blk-core.c:681 [inline]
>  __submit_bio+0x20e/0x3d0 block/blk-core.c:670
>  __submit_bio_noacct block/blk-core.c:724 [inline]
>  submit_bio_noacct_nocheck+0x736/0xc00 block/blk-core.c:792
>  submit_bio_noacct+0xc93/0x2130 block/blk-core.c:925
>  bio_await+0x1fa/0x240 block/bio.c:1580
>  submit_bio_wait+0x19/0x60 block/bio.c:1598
>  __blkdev_direct_IO_simple+0x4cb/0x8c0 block/fops.c:98
>  blkdev_direct_IO+0xbee/0x2030 block/fops.c:429
>  blkdev_direct_write block/fops.c:699 [inline]
>  blkdev_write_iter+0x703/0xd30 block/fops.c:767
>  new_sync_write fs/read_write.c:595 [inline]
>  vfs_write+0x6af/0x1050 fs/read_write.c:687
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=3fe892ea5fc292e1353f
> Tested-by: [email protected]
> Signed-off-by: Edward Adam Davis <[email protected]>
> ---
>  drivers/md/raid1.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index f0646fb24371..3b9f1fa65e65 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -1674,6 +1674,7 @@ static bool raid1_write_request(struct mddev *mddev, struct bio *bio,
>  static bool raid1_make_request(struct mddev *mddev, struct bio *bio)
>  {
>  	sector_t sectors;
> +	blk_status_t status;
>  
>  	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
>  	    && md_flush_request(mddev, bio))
> @@ -1692,11 +1693,36 @@ static bool raid1_make_request(struct mddev *mddev, struct bio *bio)
>  	if (bio_data_dir(bio) == READ)
>  		raid1_read_request(mddev, bio, sectors, NULL);
>  	else {
> +		int err;
> +
>  		md_write_start(mddev, bio);
> -		if (!raid1_write_request(mddev, bio, sectors))
> +		err = mddev_lock(mddev);
> +
> +		if (err < 0) {
> +			md_write_end(mddev);
> +			status = BLK_STS_IOERR;
> +			goto done;
> +		}
> +
> +		if (!mddev->private) {
> +			mddev_unlock(mddev);
> +			md_write_end(mddev);
> +			status = BLK_STS_OFFLINE;
> +			goto done;
> +		}
> +
> +		err = raid1_write_request(mddev, bio, sectors);
> +		mddev_unlock(mddev);
> +
> +		if (!err)
>  			md_write_end(mddev);
>  	}
> +out:
>  	return true;
> +done:
> +	bio->bi_status = status;
> +	bio_endio(bio);
> +	goto out;
>  }
>  
>  static void raid1_status(struct seq_file *seq, struct mddev *mddev)
> -- 
> 2.43.0
>
>

-- 
Best Regards,
Abd-Alrhman
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.