Commit 1df1fc8
committed
md: fix create on open mddev lifetime regression
Commit 9e59d60 ("md: call del_gendisk in control path") moves
setting MD_DELETED from __mddev_put() to do_md_stop(), however, for the
case create on open, mddev can be freed without do_md_stop():
1) open
md_probe
md_alloc_and_put
md_alloc
mddev_alloc
atomic_set(&mddev->active, 1);
mddev->hold_active = UNTIL_IOCTL
mddev_put
atomic_dec_and_test(&mddev->active)
if (mddev->hold_active)
-> active is 0, hold_active is set
md_open
mddev_get
atomic_inc(&mddev->active);
2) ioctl that is not STOP_ARRAY, for example, GET_ARRAY_INFO:
md_ioctl
mddev->hold_active = 0
3) close
md_release
mddev_put(mddev);
atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)
__mddev_put
-> hold_active is cleared, mddev will be freed
queue_work(md_misc_wq, &mddev->del_work)
Now that MD_DELETED is not set, before mddev is freed by
mddev_delayed_delete(), md_open can still succeed and break mddev
lifetime, causing mddev->kobj refcount underflow or mddev uaf
problem.
Fix this problem by setting MD_DELETED before queuing del_work.
Reported-by: [email protected]
Closes: https://lore.kernel.org/all/[email protected]/
Reported-by: [email protected]
Closes: https://lore.kernel.org/all/[email protected]/
Fixes: 9e59d60 ("md: call del_gendisk in control path")
Link: https://lore.kernel.org/linux-raid/[email protected]
Signed-off-by: Yu Kuai <[email protected]>
Reviewed-by: Paul Menzel <[email protected]>
Reviewed-by: Xiao Ni <[email protected]>1 parent 5421681 commit 1df1fc8
1 file changed
+6
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
636 | 636 | | |
637 | 637 | | |
638 | 638 | | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
639 | 645 | | |
640 | 646 | | |
641 | 647 | | |
| |||
0 commit comments