This is a note to let you know that I've just added the patch titled md: fix regression for null-ptr-deference in __md_stop() to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: md-fix-regression-for-null-ptr-deference-in-__md_stop.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 433279beba1d4872da10b7b60a539e0cb828b32b Mon Sep 17 00:00:00 2001 From: Yu Kuai <yukuai3@xxxxxxxxxx> Date: Tue, 28 Mar 2023 17:44:00 +0800 Subject: md: fix regression for null-ptr-deference in __md_stop() From: Yu Kuai <yukuai3@xxxxxxxxxx> commit 433279beba1d4872da10b7b60a539e0cb828b32b upstream. Commit 3e453522593d ("md: Free resources in __md_stop") tried to fix null-ptr-deference for 'active_io' by moving percpu_ref_exit() to __md_stop(), however, the commit also moving 'writes_pending' to __md_stop(), and this will cause mdadm tests broken: BUG: kernel NULL pointer dereference, address: 0000000000000038 Oops: 0000 [#1] PREEMPT SMP CPU: 15 PID: 17830 Comm: mdadm Not tainted 6.3.0-rc3-next-20230324-00009-g520d37 RIP: 0010:free_percpu+0x465/0x670 Call Trace: <TASK> __percpu_ref_exit+0x48/0x70 percpu_ref_exit+0x1a/0x90 __md_stop+0xe9/0x170 do_md_stop+0x1e1/0x7b0 md_ioctl+0x90c/0x1aa0 blkdev_ioctl+0x19b/0x400 vfs_ioctl+0x20/0x50 __x64_sys_ioctl+0xba/0xe0 do_syscall_64+0x6c/0xe0 entry_SYSCALL_64_after_hwframe+0x63/0xcd And the problem can be reporduced 100% by following test: mdadm -CR /dev/md0 -l1 -n1 /dev/sda --force echo inactive > /sys/block/md0/md/array_state echo read-auto > /sys/block/md0/md/array_state echo inactive > /sys/block/md0/md/array_state Root cause: // start raid raid1_run mddev_init_writes_pending percpu_ref_init // inactive raid array_state_store do_md_stop __md_stop percpu_ref_exit // start raid again array_state_store do_md_run raid1_run mddev_init_writes_pending if (mddev->writes_pending.percpu_count_ptr) // won't reinit // inactive raid again ... percpu_ref_exit -> null-ptr-deference Before the commit, 'writes_pending' is exited when mddev is freed, and it's safe to restart raid because mddev_init_writes_pending() already make sure that 'writes_pending' will only be initialized once. Fix the prblem by moving 'writes_pending' back, it's a litter hard to find the relationship between alloc memory and free memory, however, code changes is much less and we lived with this for a long time already. Fixes: 3e453522593d ("md: Free resources in __md_stop") Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> Reviewed-by: Xiao Ni <xni@xxxxxxxxxx> Signed-off-by: Song Liu <song@xxxxxxxxxx> Link: https://lore.kernel.org/r/20230328094400.1448955-1-yukuai1@xxxxxxxxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6278,7 +6278,6 @@ static void __md_stop(struct mddev *mdde module_put(pers->owner); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - percpu_ref_exit(&mddev->writes_pending); percpu_ref_exit(&mddev->active_io); bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); @@ -6293,6 +6292,7 @@ void md_stop(struct mddev *mddev) */ __md_stop_writes(mddev); __md_stop(mddev); + percpu_ref_exit(&mddev->writes_pending); } EXPORT_SYMBOL_GPL(md_stop); @@ -7859,6 +7859,7 @@ static void md_free_disk(struct gendisk { struct mddev *mddev = disk->private_data; + percpu_ref_exit(&mddev->writes_pending); mddev_free(mddev); } Patches currently in stable-queue which might be from yukuai3@xxxxxxxxxx are queue-6.1/md-fix-regression-for-null-ptr-deference-in-__md_stop.patch queue-6.1/md-raid5-cache-fix-null-ptr-deref-for-r5l_flush_stri.patch queue-6.1/md-restore-noio_flag-for-the-last-mddev_resume.patch queue-6.1/md-free-resources-in-__md_stop.patch queue-6.1/md-raid1-hold-the-barrier-until-handle_read_error-fi.patch queue-6.1/md-md-bitmap-hold-reconfig_mutex-in-backlog_store.patch queue-6.1/md-raid0-fix-performance-regression-for-large-sequen.patch queue-6.1/md-raid5-cache-fix-a-deadlock-in-r5l_exit_log.patch queue-6.1/md-md-bitmap-remove-unnecessary-local-variable-in-ba.patch queue-6.1/md-raid0-account-for-split-bio-in-iostat-accounting.patch queue-6.1/md-raid0-factor-out-helper-for-mapping-and-submittin.patch queue-6.1/md-raid1-free-the-r1bio-before-waiting-for-blocked-r.patch