]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some md patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Aug 2025 06:49:49 +0000 (08:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Aug 2025 06:50:15 +0000 (08:50 +0200)
16 files changed:
queue-6.12/md-call-del_gendisk-in-control-path.patch [deleted file]
queue-6.12/md-don-t-clear-md_closing-until-mddev-is-freed.patch [deleted file]
queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch [deleted file]
queue-6.12/series
queue-6.15/md-call-del_gendisk-in-control-path.patch [deleted file]
queue-6.15/md-don-t-clear-md_closing-until-mddev-is-freed.patch [deleted file]
queue-6.15/md-fix-create-on-open-mddev-lifetime-regression.patch [deleted file]
queue-6.15/series
queue-6.16/md-call-del_gendisk-in-control-path.patch [deleted file]
queue-6.16/md-don-t-clear-md_closing-until-mddev-is-freed.patch [deleted file]
queue-6.16/md-fix-create-on-open-mddev-lifetime-regression.patch [deleted file]
queue-6.16/series
queue-6.6/md-call-del_gendisk-in-control-path.patch [deleted file]
queue-6.6/md-don-t-clear-md_closing-until-mddev-is-freed.patch [deleted file]
queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch [deleted file]
queue-6.6/series

diff --git a/queue-6.12/md-call-del_gendisk-in-control-path.patch b/queue-6.12/md-call-del_gendisk-in-control-path.patch
deleted file mode 100644 (file)
index 5ed439b..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From ff0b64256d28c7fe0d141fbd210bef93233a6461 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:06 +0800
-Subject: md: call del_gendisk in control path
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 9e59d609763f70a992a8f3808dabcce60f14eb5c ]
-
-Now del_gendisk and put_disk are called asynchronously in workqueue work.
-The asynchronous way has a problem that the device node can still exist
-after mdadm --stop command returns in a short window. So udev rule can
-open this device node and create the struct mddev in kernel again. So put
-del_gendisk in control path and still leave put_disk in md_kobj_release
-to avoid uaf of gendisk.
-
-Function del_gendisk can't be called with reconfig_mutex. If it's called
-with reconfig mutex, a deadlock can happen. del_gendisk waits all sysfs
-files access to finish and sysfs file access waits reconfig mutex. So
-put del_gendisk after releasing reconfig mutex.
-
-But there is still a window that sysfs can be accessed between mddev_unlock
-and del_gendisk. So some actions (add disk, change level, .e.g) can happen
-which lead unexpected results. MD_DELETED is used to resolve this problem.
-MD_DELETED is set before releasing reconfig mutex and it should be checked
-for these sysfs access which need reconfig mutex. For sysfs access which
-don't need reconfig mutex, del_gendisk will wait them to finish.
-
-But it doesn't need to do this in function mddev_lock_nointr. There are
-ten places that call it.
-* Five of them are in dm raid which we don't need to care. MD_DELETED is
-only used for md raid.
-* stop_sync_thread, md_do_sync and md_start_sync are related sync request,
-and it needs to wait sync thread to finish before stopping an array.
-* md_ioctl: md_open is called before md_ioctl, so ->openers is added. It
-will fail to stop the array. So it doesn't need to check MD_DELETED here
-* md_set_readonly:
-It needs to call mddev_set_closing_and_sync_blockdev when setting readonly
-or read_auto. So it will fail to stop the array too because MD_CLOSING is
-already set.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-2-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 33 +++++++++++++++++++++++----------
- drivers/md/md.h | 26 ++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 4b3291723670..91cece996250 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -619,9 +619,6 @@ static void __mddev_put(struct mddev *mddev)
-           mddev->ctime || mddev->hold_active)
-               return;
--      /* Array is not configured at all, and not held active, so destroy it */
--      set_bit(MD_DELETED, &mddev->flags);
--
-       /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-@@ -856,6 +853,16 @@ void mddev_unlock(struct mddev *mddev)
-               kobject_del(&rdev->kobj);
-               export_rdev(rdev, mddev);
-       }
-+
-+      /* Call del_gendisk after release reconfig_mutex to avoid
-+       * deadlock (e.g. call del_gendisk under the lock and an
-+       * access to sysfs files waits the lock)
-+       * And MD_DELETED is only used for md raid which is set in
-+       * do_md_stop. dm raid only uses md_stop to stop. So dm raid
-+       * doesn't need to check MD_DELETED when getting reconfig lock
-+       */
-+      if (test_bit(MD_DELETED, &mddev->flags))
-+              del_gendisk(mddev->gendisk);
- }
- EXPORT_SYMBOL_GPL(mddev_unlock);
-@@ -5720,19 +5727,30 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
-       struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
-       struct mddev *mddev = container_of(kobj, struct mddev, kobj);
-       ssize_t rv;
-+      struct kernfs_node *kn = NULL;
-       if (!entry->store)
-               return -EIO;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-+
-+      if (entry->store == array_state_store && cmd_match(page, "clear"))
-+              kn = sysfs_break_active_protection(kobj, attr);
-+
-       spin_lock(&all_mddevs_lock);
-       if (!mddev_get(mddev)) {
-               spin_unlock(&all_mddevs_lock);
-+              if (kn)
-+                      sysfs_unbreak_active_protection(kn);
-               return -EBUSY;
-       }
-       spin_unlock(&all_mddevs_lock);
-       rv = entry->store(mddev, page, length);
-       mddev_put(mddev);
-+
-+      if (kn)
-+              sysfs_unbreak_active_protection(kn);
-+
-       return rv;
- }
-@@ -5740,12 +5758,6 @@ static void md_kobj_release(struct kobject *ko)
- {
-       struct mddev *mddev = container_of(ko, struct mddev, kobj);
--      if (mddev->sysfs_state)
--              sysfs_put(mddev->sysfs_state);
--      if (mddev->sysfs_level)
--              sysfs_put(mddev->sysfs_level);
--
--      del_gendisk(mddev->gendisk);
-       put_disk(mddev->gendisk);
- }
-@@ -6601,8 +6613,9 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               mddev->bitmap_info.offset = 0;
-               export_array(mddev);
--
-               md_clean(mddev);
-+              set_bit(MD_DELETED, &mddev->flags);
-+
-               if (mddev->hold_active == UNTIL_STOP)
-                       mddev->hold_active = 0;
-       }
-diff --git a/drivers/md/md.h b/drivers/md/md.h
-index 8826dce9717d..cf06a9de6f19 100644
---- a/drivers/md/md.h
-+++ b/drivers/md/md.h
-@@ -669,11 +669,26 @@ static inline bool reshape_interrupted(struct mddev *mddev)
- static inline int __must_check mddev_lock(struct mddev *mddev)
- {
--      return mutex_lock_interruptible(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
-+
-+      /* MD_DELETED is set in do_md_stop with reconfig_mutex.
-+       * So check it here.
-+       */
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+
-+      return ret;
- }
- /* Sometimes we need to take the lock in a situation where
-  * failure due to interrupts is not acceptable.
-+ * It doesn't need to check MD_DELETED here, the owner which
-+ * holds the lock here can't be stopped. And all paths can't
-+ * call this function after do_md_stop.
-  */
- static inline void mddev_lock_nointr(struct mddev *mddev)
- {
-@@ -682,7 +697,14 @@ static inline void mddev_lock_nointr(struct mddev *mddev)
- static inline int mddev_trylock(struct mddev *mddev)
- {
--      return mutex_trylock(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_trylock(&mddev->reconfig_mutex);
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+      return ret;
- }
- extern void mddev_unlock(struct mddev *mddev);
--- 
-2.39.5
-
diff --git a/queue-6.12/md-don-t-clear-md_closing-until-mddev-is-freed.patch b/queue-6.12/md-don-t-clear-md_closing-until-mddev-is-freed.patch
deleted file mode 100644 (file)
index fbb03d1..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From 880e342d560e6fd3280ec8a359395bcc2f4e1f04 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:07 +0800
-Subject: md: Don't clear MD_CLOSING until mddev is freed
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 5f286f33553d600e6c2fb5a23dd6afcf99b3ebac ]
-
-UNTIL_STOP is used to avoid mddev is freed on the last close before adding
-disks to mddev. And it should be cleared when stopping an array which is
-mentioned in commit efeb53c0e572 ("md: Allow md devices to be created by
-name."). So reset ->hold_active to 0 in md_clean.
-
-And MD_CLOSING should be kept until mddev is freed to avoid reopen.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-3-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 16 ++++------------
- 1 file changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 91cece996250..6b5b69a7a3f0 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -6380,15 +6380,10 @@ static void md_clean(struct mddev *mddev)
-       mddev->persistent = 0;
-       mddev->level = LEVEL_NONE;
-       mddev->clevel[0] = 0;
--      /*
--       * Don't clear MD_CLOSING, or mddev can be opened again.
--       * 'hold_active != 0' means mddev is still in the creation
--       * process and will be used later.
--       */
--      if (mddev->hold_active)
--              mddev->flags = 0;
--      else
--              mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-+      /* if UNTIL_STOP is set, it's cleared here */
-+      mddev->hold_active = 0;
-+      /* Don't clear MD_CLOSING, or mddev can be opened again. */
-+      mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-       mddev->sb_flags = 0;
-       mddev->ro = MD_RDWR;
-       mddev->metadata_type[0] = 0;
-@@ -6615,9 +6610,6 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               export_array(mddev);
-               md_clean(mddev);
-               set_bit(MD_DELETED, &mddev->flags);
--
--              if (mddev->hold_active == UNTIL_STOP)
--                      mddev->hold_active = 0;
-       }
-       md_new_event();
-       sysfs_notify_dirent_safe(mddev->sysfs_state);
--- 
-2.39.5
-
diff --git a/queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.12/md-fix-create-on-open-mddev-lifetime-regression.patch
deleted file mode 100644 (file)
index 14ab850..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001
-From: Yu Kuai <yukuai3@huawei.com>
-Date: Wed, 30 Jul 2025 15:33:21 +0800
-Subject: md: fix create on open mddev lifetime regression
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream.
-
-Commit 9e59d609763f ("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: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/
-Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/
-Fixes: 9e59d609763f ("md: call del_gendisk in control path")
-Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
-Reviewed-by: Xiao Ni <xni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/md/md.c |    6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -620,6 +620,12 @@ static void __mddev_put(struct mddev *md
-               return;
-       /*
-+       * If array is freed by stopping array, MD_DELETED is set by
-+       * do_md_stop(), MD_DELETED is still set here in case mddev is freed
-+       * directly by closing a mddev that is created by create_on_open.
-+       */
-+      set_bit(MD_DELETED, &mddev->flags);
-+      /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-        */
index 047afb62c1089956487b73497381bff08eae4a4f..646d12e35a06aac0cf3e5698ad16a10c7c37fb2e 100644 (file)
@@ -75,7 +75,6 @@ md-raid10-set-chunk_sectors-limit.patch
 nvme-tcp-log-tls-handshake-failures-at-error-level.patch
 gfs2-validate-i_depth-for-exhash-directories.patch
 gfs2-set-.migrate_folio-in-gfs2_-rgrp-meta-_aops.patch
-md-call-del_gendisk-in-control-path.patch
 loop-avoid-updating-block-size-under-exclusive-owner.patch
 udf-verify-partition-map-count.patch
 drbd-add-missing-kref_get-in-handle_write_conflicts.patch
@@ -86,7 +85,6 @@ ata-ahci-disable-dipm-if-host-lacks-support.patch
 ata-libata-sata-disallow-changing-lpm-state-if-not-s.patch
 fs-ntfs3-add-sanity-check-for-file-name.patch
 fs-ntfs3-correctly-create-symlink-for-relative-path.patch
-md-don-t-clear-md_closing-until-mddev-is-freed.patch
 pidfs-raise-sb_i_nodev-and-sb_i_noexec.patch
 ext2-handle-fiemap-on-empty-files-to-prevent-einval.patch
 fix-locking-in-efi_secret_unlink.patch
@@ -437,7 +435,6 @@ ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch
 io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch
 firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch
 drm-amd-display-allow-dcn301-to-clear-update-flags.patch
-md-fix-create-on-open-mddev-lifetime-regression.patch
 rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch
 dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch
 pci-honor-max-link-speed-when-determining-supported-speeds.patch
diff --git a/queue-6.15/md-call-del_gendisk-in-control-path.patch b/queue-6.15/md-call-del_gendisk-in-control-path.patch
deleted file mode 100644 (file)
index e8fbacb..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From b47c5676ac28d0b0ce7e97be53bba3c761ab7552 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:06 +0800
-Subject: md: call del_gendisk in control path
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 9e59d609763f70a992a8f3808dabcce60f14eb5c ]
-
-Now del_gendisk and put_disk are called asynchronously in workqueue work.
-The asynchronous way has a problem that the device node can still exist
-after mdadm --stop command returns in a short window. So udev rule can
-open this device node and create the struct mddev in kernel again. So put
-del_gendisk in control path and still leave put_disk in md_kobj_release
-to avoid uaf of gendisk.
-
-Function del_gendisk can't be called with reconfig_mutex. If it's called
-with reconfig mutex, a deadlock can happen. del_gendisk waits all sysfs
-files access to finish and sysfs file access waits reconfig mutex. So
-put del_gendisk after releasing reconfig mutex.
-
-But there is still a window that sysfs can be accessed between mddev_unlock
-and del_gendisk. So some actions (add disk, change level, .e.g) can happen
-which lead unexpected results. MD_DELETED is used to resolve this problem.
-MD_DELETED is set before releasing reconfig mutex and it should be checked
-for these sysfs access which need reconfig mutex. For sysfs access which
-don't need reconfig mutex, del_gendisk will wait them to finish.
-
-But it doesn't need to do this in function mddev_lock_nointr. There are
-ten places that call it.
-* Five of them are in dm raid which we don't need to care. MD_DELETED is
-only used for md raid.
-* stop_sync_thread, md_do_sync and md_start_sync are related sync request,
-and it needs to wait sync thread to finish before stopping an array.
-* md_ioctl: md_open is called before md_ioctl, so ->openers is added. It
-will fail to stop the array. So it doesn't need to check MD_DELETED here
-* md_set_readonly:
-It needs to call mddev_set_closing_and_sync_blockdev when setting readonly
-or read_auto. So it will fail to stop the array too because MD_CLOSING is
-already set.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-2-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 33 +++++++++++++++++++++++----------
- drivers/md/md.h | 26 ++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 47f3253c4757..aa053bb818bc 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -613,9 +613,6 @@ static void __mddev_put(struct mddev *mddev)
-           mddev->ctime || mddev->hold_active)
-               return;
--      /* Array is not configured at all, and not held active, so destroy it */
--      set_bit(MD_DELETED, &mddev->flags);
--
-       /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-@@ -850,6 +847,16 @@ void mddev_unlock(struct mddev *mddev)
-               kobject_del(&rdev->kobj);
-               export_rdev(rdev, mddev);
-       }
-+
-+      /* Call del_gendisk after release reconfig_mutex to avoid
-+       * deadlock (e.g. call del_gendisk under the lock and an
-+       * access to sysfs files waits the lock)
-+       * And MD_DELETED is only used for md raid which is set in
-+       * do_md_stop. dm raid only uses md_stop to stop. So dm raid
-+       * doesn't need to check MD_DELETED when getting reconfig lock
-+       */
-+      if (test_bit(MD_DELETED, &mddev->flags))
-+              del_gendisk(mddev->gendisk);
- }
- EXPORT_SYMBOL_GPL(mddev_unlock);
-@@ -5721,19 +5728,30 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
-       struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
-       struct mddev *mddev = container_of(kobj, struct mddev, kobj);
-       ssize_t rv;
-+      struct kernfs_node *kn = NULL;
-       if (!entry->store)
-               return -EIO;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-+
-+      if (entry->store == array_state_store && cmd_match(page, "clear"))
-+              kn = sysfs_break_active_protection(kobj, attr);
-+
-       spin_lock(&all_mddevs_lock);
-       if (!mddev_get(mddev)) {
-               spin_unlock(&all_mddevs_lock);
-+              if (kn)
-+                      sysfs_unbreak_active_protection(kn);
-               return -EBUSY;
-       }
-       spin_unlock(&all_mddevs_lock);
-       rv = entry->store(mddev, page, length);
-       mddev_put(mddev);
-+
-+      if (kn)
-+              sysfs_unbreak_active_protection(kn);
-+
-       return rv;
- }
-@@ -5741,12 +5759,6 @@ static void md_kobj_release(struct kobject *ko)
- {
-       struct mddev *mddev = container_of(ko, struct mddev, kobj);
--      if (mddev->sysfs_state)
--              sysfs_put(mddev->sysfs_state);
--      if (mddev->sysfs_level)
--              sysfs_put(mddev->sysfs_level);
--
--      del_gendisk(mddev->gendisk);
-       put_disk(mddev->gendisk);
- }
-@@ -6593,8 +6605,9 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               mddev->bitmap_info.offset = 0;
-               export_array(mddev);
--
-               md_clean(mddev);
-+              set_bit(MD_DELETED, &mddev->flags);
-+
-               if (mddev->hold_active == UNTIL_STOP)
-                       mddev->hold_active = 0;
-       }
-diff --git a/drivers/md/md.h b/drivers/md/md.h
-index 1cf00a04bcdd..b851fc0dc085 100644
---- a/drivers/md/md.h
-+++ b/drivers/md/md.h
-@@ -697,11 +697,26 @@ static inline bool reshape_interrupted(struct mddev *mddev)
- static inline int __must_check mddev_lock(struct mddev *mddev)
- {
--      return mutex_lock_interruptible(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
-+
-+      /* MD_DELETED is set in do_md_stop with reconfig_mutex.
-+       * So check it here.
-+       */
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+
-+      return ret;
- }
- /* Sometimes we need to take the lock in a situation where
-  * failure due to interrupts is not acceptable.
-+ * It doesn't need to check MD_DELETED here, the owner which
-+ * holds the lock here can't be stopped. And all paths can't
-+ * call this function after do_md_stop.
-  */
- static inline void mddev_lock_nointr(struct mddev *mddev)
- {
-@@ -710,7 +725,14 @@ static inline void mddev_lock_nointr(struct mddev *mddev)
- static inline int mddev_trylock(struct mddev *mddev)
- {
--      return mutex_trylock(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_trylock(&mddev->reconfig_mutex);
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+      return ret;
- }
- extern void mddev_unlock(struct mddev *mddev);
--- 
-2.39.5
-
diff --git a/queue-6.15/md-don-t-clear-md_closing-until-mddev-is-freed.patch b/queue-6.15/md-don-t-clear-md_closing-until-mddev-is-freed.patch
deleted file mode 100644 (file)
index c52f896..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From 5f84794f063aaab62d86317011de7cc392c66111 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:07 +0800
-Subject: md: Don't clear MD_CLOSING until mddev is freed
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 5f286f33553d600e6c2fb5a23dd6afcf99b3ebac ]
-
-UNTIL_STOP is used to avoid mddev is freed on the last close before adding
-disks to mddev. And it should be cleared when stopping an array which is
-mentioned in commit efeb53c0e572 ("md: Allow md devices to be created by
-name."). So reset ->hold_active to 0 in md_clean.
-
-And MD_CLOSING should be kept until mddev is freed to avoid reopen.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-3-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 16 ++++------------
- 1 file changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index aa053bb818bc..13a6287e7415 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -6372,15 +6372,10 @@ static void md_clean(struct mddev *mddev)
-       mddev->persistent = 0;
-       mddev->level = LEVEL_NONE;
-       mddev->clevel[0] = 0;
--      /*
--       * Don't clear MD_CLOSING, or mddev can be opened again.
--       * 'hold_active != 0' means mddev is still in the creation
--       * process and will be used later.
--       */
--      if (mddev->hold_active)
--              mddev->flags = 0;
--      else
--              mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-+      /* if UNTIL_STOP is set, it's cleared here */
-+      mddev->hold_active = 0;
-+      /* Don't clear MD_CLOSING, or mddev can be opened again. */
-+      mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-       mddev->sb_flags = 0;
-       mddev->ro = MD_RDWR;
-       mddev->metadata_type[0] = 0;
-@@ -6607,9 +6602,6 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               export_array(mddev);
-               md_clean(mddev);
-               set_bit(MD_DELETED, &mddev->flags);
--
--              if (mddev->hold_active == UNTIL_STOP)
--                      mddev->hold_active = 0;
-       }
-       md_new_event();
-       sysfs_notify_dirent_safe(mddev->sysfs_state);
--- 
-2.39.5
-
diff --git a/queue-6.15/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.15/md-fix-create-on-open-mddev-lifetime-regression.patch
deleted file mode 100644 (file)
index 936540f..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001
-From: Yu Kuai <yukuai3@huawei.com>
-Date: Wed, 30 Jul 2025 15:33:21 +0800
-Subject: md: fix create on open mddev lifetime regression
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream.
-
-Commit 9e59d609763f ("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: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/
-Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/
-Fixes: 9e59d609763f ("md: call del_gendisk in control path")
-Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
-Reviewed-by: Xiao Ni <xni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/md/md.c |    6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -614,6 +614,12 @@ static void __mddev_put(struct mddev *md
-               return;
-       /*
-+       * If array is freed by stopping array, MD_DELETED is set by
-+       * do_md_stop(), MD_DELETED is still set here in case mddev is freed
-+       * directly by closing a mddev that is created by create_on_open.
-+       */
-+      set_bit(MD_DELETED, &mddev->flags);
-+      /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-        */
index 5780a341676ef0317e2b572d1f07312ec76d5f9c..916adbf597e2d50d157fc240734fcdec47c91f33 100644 (file)
@@ -91,7 +91,6 @@ md-raid10-set-chunk_sectors-limit.patch
 nvme-tcp-log-tls-handshake-failures-at-error-level.patch
 gfs2-validate-i_depth-for-exhash-directories.patch
 gfs2-set-.migrate_folio-in-gfs2_-rgrp-meta-_aops.patch
-md-call-del_gendisk-in-control-path.patch
 loop-avoid-updating-block-size-under-exclusive-owner.patch
 udf-verify-partition-map-count.patch
 drbd-add-missing-kref_get-in-handle_write_conflicts.patch
@@ -102,7 +101,6 @@ ata-ahci-disable-dipm-if-host-lacks-support.patch
 ata-libata-sata-disallow-changing-lpm-state-if-not-s.patch
 fs-ntfs3-add-sanity-check-for-file-name.patch
 fs-ntfs3-correctly-create-symlink-for-relative-path.patch
-md-don-t-clear-md_closing-until-mddev-is-freed.patch
 pidfs-raise-sb_i_nodev-and-sb_i_noexec.patch
 landlock-opened-file-never-has-a-negative-dentry.patch
 ext2-handle-fiemap-on-empty-files-to-prevent-einval.patch
@@ -509,6 +507,5 @@ ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch
 io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch
 firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch
 drm-amd-display-allow-dcn301-to-clear-update-flags.patch
-md-fix-create-on-open-mddev-lifetime-regression.patch
 rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch
 dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch
diff --git a/queue-6.16/md-call-del_gendisk-in-control-path.patch b/queue-6.16/md-call-del_gendisk-in-control-path.patch
deleted file mode 100644 (file)
index db43677..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From bbd219cd5c5f8380c07ab02a591bd0c557d43c86 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:06 +0800
-Subject: md: call del_gendisk in control path
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 9e59d609763f70a992a8f3808dabcce60f14eb5c ]
-
-Now del_gendisk and put_disk are called asynchronously in workqueue work.
-The asynchronous way has a problem that the device node can still exist
-after mdadm --stop command returns in a short window. So udev rule can
-open this device node and create the struct mddev in kernel again. So put
-del_gendisk in control path and still leave put_disk in md_kobj_release
-to avoid uaf of gendisk.
-
-Function del_gendisk can't be called with reconfig_mutex. If it's called
-with reconfig mutex, a deadlock can happen. del_gendisk waits all sysfs
-files access to finish and sysfs file access waits reconfig mutex. So
-put del_gendisk after releasing reconfig mutex.
-
-But there is still a window that sysfs can be accessed between mddev_unlock
-and del_gendisk. So some actions (add disk, change level, .e.g) can happen
-which lead unexpected results. MD_DELETED is used to resolve this problem.
-MD_DELETED is set before releasing reconfig mutex and it should be checked
-for these sysfs access which need reconfig mutex. For sysfs access which
-don't need reconfig mutex, del_gendisk will wait them to finish.
-
-But it doesn't need to do this in function mddev_lock_nointr. There are
-ten places that call it.
-* Five of them are in dm raid which we don't need to care. MD_DELETED is
-only used for md raid.
-* stop_sync_thread, md_do_sync and md_start_sync are related sync request,
-and it needs to wait sync thread to finish before stopping an array.
-* md_ioctl: md_open is called before md_ioctl, so ->openers is added. It
-will fail to stop the array. So it doesn't need to check MD_DELETED here
-* md_set_readonly:
-It needs to call mddev_set_closing_and_sync_blockdev when setting readonly
-or read_auto. So it will fail to stop the array too because MD_CLOSING is
-already set.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-2-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 33 +++++++++++++++++++++++----------
- drivers/md/md.h | 26 ++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 10670c62b09e..c16c7feb6034 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -636,9 +636,6 @@ static void __mddev_put(struct mddev *mddev)
-           mddev->ctime || mddev->hold_active)
-               return;
--      /* Array is not configured at all, and not held active, so destroy it */
--      set_bit(MD_DELETED, &mddev->flags);
--
-       /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-@@ -873,6 +870,16 @@ void mddev_unlock(struct mddev *mddev)
-               kobject_del(&rdev->kobj);
-               export_rdev(rdev, mddev);
-       }
-+
-+      /* Call del_gendisk after release reconfig_mutex to avoid
-+       * deadlock (e.g. call del_gendisk under the lock and an
-+       * access to sysfs files waits the lock)
-+       * And MD_DELETED is only used for md raid which is set in
-+       * do_md_stop. dm raid only uses md_stop to stop. So dm raid
-+       * doesn't need to check MD_DELETED when getting reconfig lock
-+       */
-+      if (test_bit(MD_DELETED, &mddev->flags))
-+              del_gendisk(mddev->gendisk);
- }
- EXPORT_SYMBOL_GPL(mddev_unlock);
-@@ -5774,19 +5781,30 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
-       struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
-       struct mddev *mddev = container_of(kobj, struct mddev, kobj);
-       ssize_t rv;
-+      struct kernfs_node *kn = NULL;
-       if (!entry->store)
-               return -EIO;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-+
-+      if (entry->store == array_state_store && cmd_match(page, "clear"))
-+              kn = sysfs_break_active_protection(kobj, attr);
-+
-       spin_lock(&all_mddevs_lock);
-       if (!mddev_get(mddev)) {
-               spin_unlock(&all_mddevs_lock);
-+              if (kn)
-+                      sysfs_unbreak_active_protection(kn);
-               return -EBUSY;
-       }
-       spin_unlock(&all_mddevs_lock);
-       rv = entry->store(mddev, page, length);
-       mddev_put(mddev);
-+
-+      if (kn)
-+              sysfs_unbreak_active_protection(kn);
-+
-       return rv;
- }
-@@ -5794,12 +5812,6 @@ static void md_kobj_release(struct kobject *ko)
- {
-       struct mddev *mddev = container_of(ko, struct mddev, kobj);
--      if (mddev->sysfs_state)
--              sysfs_put(mddev->sysfs_state);
--      if (mddev->sysfs_level)
--              sysfs_put(mddev->sysfs_level);
--
--      del_gendisk(mddev->gendisk);
-       put_disk(mddev->gendisk);
- }
-@@ -6646,8 +6658,9 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               mddev->bitmap_info.offset = 0;
-               export_array(mddev);
--
-               md_clean(mddev);
-+              set_bit(MD_DELETED, &mddev->flags);
-+
-               if (mddev->hold_active == UNTIL_STOP)
-                       mddev->hold_active = 0;
-       }
-diff --git a/drivers/md/md.h b/drivers/md/md.h
-index d45a9e6ead80..67b365621507 100644
---- a/drivers/md/md.h
-+++ b/drivers/md/md.h
-@@ -700,11 +700,26 @@ static inline bool reshape_interrupted(struct mddev *mddev)
- static inline int __must_check mddev_lock(struct mddev *mddev)
- {
--      return mutex_lock_interruptible(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
-+
-+      /* MD_DELETED is set in do_md_stop with reconfig_mutex.
-+       * So check it here.
-+       */
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+
-+      return ret;
- }
- /* Sometimes we need to take the lock in a situation where
-  * failure due to interrupts is not acceptable.
-+ * It doesn't need to check MD_DELETED here, the owner which
-+ * holds the lock here can't be stopped. And all paths can't
-+ * call this function after do_md_stop.
-  */
- static inline void mddev_lock_nointr(struct mddev *mddev)
- {
-@@ -713,7 +728,14 @@ static inline void mddev_lock_nointr(struct mddev *mddev)
- static inline int mddev_trylock(struct mddev *mddev)
- {
--      return mutex_trylock(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_trylock(&mddev->reconfig_mutex);
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+      return ret;
- }
- extern void mddev_unlock(struct mddev *mddev);
--- 
-2.39.5
-
diff --git a/queue-6.16/md-don-t-clear-md_closing-until-mddev-is-freed.patch b/queue-6.16/md-don-t-clear-md_closing-until-mddev-is-freed.patch
deleted file mode 100644 (file)
index 073d159..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From 2c6366ab6d14425f251da6bccb6f1dde7ed2459a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:07 +0800
-Subject: md: Don't clear MD_CLOSING until mddev is freed
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 5f286f33553d600e6c2fb5a23dd6afcf99b3ebac ]
-
-UNTIL_STOP is used to avoid mddev is freed on the last close before adding
-disks to mddev. And it should be cleared when stopping an array which is
-mentioned in commit efeb53c0e572 ("md: Allow md devices to be created by
-name."). So reset ->hold_active to 0 in md_clean.
-
-And MD_CLOSING should be kept until mddev is freed to avoid reopen.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-3-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 16 ++++------------
- 1 file changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index c16c7feb6034..81d786a3851b 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -6425,15 +6425,10 @@ static void md_clean(struct mddev *mddev)
-       mddev->persistent = 0;
-       mddev->level = LEVEL_NONE;
-       mddev->clevel[0] = 0;
--      /*
--       * Don't clear MD_CLOSING, or mddev can be opened again.
--       * 'hold_active != 0' means mddev is still in the creation
--       * process and will be used later.
--       */
--      if (mddev->hold_active)
--              mddev->flags = 0;
--      else
--              mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-+      /* if UNTIL_STOP is set, it's cleared here */
-+      mddev->hold_active = 0;
-+      /* Don't clear MD_CLOSING, or mddev can be opened again. */
-+      mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-       mddev->sb_flags = 0;
-       mddev->ro = MD_RDWR;
-       mddev->metadata_type[0] = 0;
-@@ -6660,9 +6655,6 @@ static int do_md_stop(struct mddev *mddev, int mode)
-               export_array(mddev);
-               md_clean(mddev);
-               set_bit(MD_DELETED, &mddev->flags);
--
--              if (mddev->hold_active == UNTIL_STOP)
--                      mddev->hold_active = 0;
-       }
-       md_new_event();
-       sysfs_notify_dirent_safe(mddev->sysfs_state);
--- 
-2.39.5
-
diff --git a/queue-6.16/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.16/md-fix-create-on-open-mddev-lifetime-regression.patch
deleted file mode 100644 (file)
index eb499b4..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001
-From: Yu Kuai <yukuai3@huawei.com>
-Date: Wed, 30 Jul 2025 15:33:21 +0800
-Subject: md: fix create on open mddev lifetime regression
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream.
-
-Commit 9e59d609763f ("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: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/
-Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/
-Fixes: 9e59d609763f ("md: call del_gendisk in control path")
-Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
-Reviewed-by: Xiao Ni <xni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/md/md.c |    6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -637,6 +637,12 @@ static void __mddev_put(struct mddev *md
-               return;
-       /*
-+       * If array is freed by stopping array, MD_DELETED is set by
-+       * do_md_stop(), MD_DELETED is still set here in case mddev is freed
-+       * directly by closing a mddev that is created by create_on_open.
-+       */
-+      set_bit(MD_DELETED, &mddev->flags);
-+      /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-        */
index 5e3e991ac42bc729502f4f3d58e53af51203ea18..b0ee6fe052021c04527755c60a5951449f5c46c7 100644 (file)
@@ -103,7 +103,6 @@ md-raid10-set-chunk_sectors-limit.patch
 nvme-tcp-log-tls-handshake-failures-at-error-level.patch
 gfs2-validate-i_depth-for-exhash-directories.patch
 gfs2-set-.migrate_folio-in-gfs2_-rgrp-meta-_aops.patch
-md-call-del_gendisk-in-control-path.patch
 loop-avoid-updating-block-size-under-exclusive-owner.patch
 udf-verify-partition-map-count.patch
 drbd-add-missing-kref_get-in-handle_write_conflicts.patch
@@ -114,7 +113,6 @@ ata-ahci-disable-dipm-if-host-lacks-support.patch
 ata-libata-sata-disallow-changing-lpm-state-if-not-s.patch
 fs-ntfs3-add-sanity-check-for-file-name.patch
 fs-ntfs3-correctly-create-symlink-for-relative-path.patch
-md-don-t-clear-md_closing-until-mddev-is-freed.patch
 pidfs-raise-sb_i_nodev-and-sb_i_noexec.patch
 landlock-opened-file-never-has-a-negative-dentry.patch
 ext2-handle-fiemap-on-empty-files-to-prevent-einval.patch
@@ -561,7 +559,6 @@ ata-libata-sata-add-link_power_management_supported-sysfs-attribute.patch
 io_uring-rw-cast-rw-flags-assignment-to-rwf_t.patch
 firmware-arm_scmi-convert-to-system_sleep_pm_ops.patch
 drm-amd-display-allow-dcn301-to-clear-update-flags.patch
-md-fix-create-on-open-mddev-lifetime-regression.patch
 rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch
 irqchip-mvebu-gicp-use-resource_size-for-ioremap.patch
 dm-split-write-bios-on-zone-boundaries-when-zone-append-is-not-emulated.patch
diff --git a/queue-6.6/md-call-del_gendisk-in-control-path.patch b/queue-6.6/md-call-del_gendisk-in-control-path.patch
deleted file mode 100644 (file)
index 2ed17b8..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From fa738623105e2dd4865274dc8525856feaec3ae9 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:06 +0800
-Subject: md: call del_gendisk in control path
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 9e59d609763f70a992a8f3808dabcce60f14eb5c ]
-
-Now del_gendisk and put_disk are called asynchronously in workqueue work.
-The asynchronous way has a problem that the device node can still exist
-after mdadm --stop command returns in a short window. So udev rule can
-open this device node and create the struct mddev in kernel again. So put
-del_gendisk in control path and still leave put_disk in md_kobj_release
-to avoid uaf of gendisk.
-
-Function del_gendisk can't be called with reconfig_mutex. If it's called
-with reconfig mutex, a deadlock can happen. del_gendisk waits all sysfs
-files access to finish and sysfs file access waits reconfig mutex. So
-put del_gendisk after releasing reconfig mutex.
-
-But there is still a window that sysfs can be accessed between mddev_unlock
-and del_gendisk. So some actions (add disk, change level, .e.g) can happen
-which lead unexpected results. MD_DELETED is used to resolve this problem.
-MD_DELETED is set before releasing reconfig mutex and it should be checked
-for these sysfs access which need reconfig mutex. For sysfs access which
-don't need reconfig mutex, del_gendisk will wait them to finish.
-
-But it doesn't need to do this in function mddev_lock_nointr. There are
-ten places that call it.
-* Five of them are in dm raid which we don't need to care. MD_DELETED is
-only used for md raid.
-* stop_sync_thread, md_do_sync and md_start_sync are related sync request,
-and it needs to wait sync thread to finish before stopping an array.
-* md_ioctl: md_open is called before md_ioctl, so ->openers is added. It
-will fail to stop the array. So it doesn't need to check MD_DELETED here
-* md_set_readonly:
-It needs to call mddev_set_closing_and_sync_blockdev when setting readonly
-or read_auto. So it will fail to stop the array too because MD_CLOSING is
-already set.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-2-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 33 +++++++++++++++++++++++----------
- drivers/md/md.h | 26 ++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index b086cbf24086..8e3939c0d2ed 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -639,9 +639,6 @@ static void __mddev_put(struct mddev *mddev)
-           mddev->ctime || mddev->hold_active)
-               return;
--      /* Array is not configured at all, and not held active, so destroy it */
--      set_bit(MD_DELETED, &mddev->flags);
--
-       /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-@@ -837,6 +834,16 @@ void mddev_unlock(struct mddev *mddev)
-               kobject_del(&rdev->kobj);
-               export_rdev(rdev, mddev);
-       }
-+
-+      /* Call del_gendisk after release reconfig_mutex to avoid
-+       * deadlock (e.g. call del_gendisk under the lock and an
-+       * access to sysfs files waits the lock)
-+       * And MD_DELETED is only used for md raid which is set in
-+       * do_md_stop. dm raid only uses md_stop to stop. So dm raid
-+       * doesn't need to check MD_DELETED when getting reconfig lock
-+       */
-+      if (test_bit(MD_DELETED, &mddev->flags))
-+              del_gendisk(mddev->gendisk);
- }
- EXPORT_SYMBOL_GPL(mddev_unlock);
-@@ -5616,19 +5623,30 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
-       struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
-       struct mddev *mddev = container_of(kobj, struct mddev, kobj);
-       ssize_t rv;
-+      struct kernfs_node *kn = NULL;
-       if (!entry->store)
-               return -EIO;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-+
-+      if (entry->store == array_state_store && cmd_match(page, "clear"))
-+              kn = sysfs_break_active_protection(kobj, attr);
-+
-       spin_lock(&all_mddevs_lock);
-       if (!mddev_get(mddev)) {
-               spin_unlock(&all_mddevs_lock);
-+              if (kn)
-+                      sysfs_unbreak_active_protection(kn);
-               return -EBUSY;
-       }
-       spin_unlock(&all_mddevs_lock);
-       rv = entry->store(mddev, page, length);
-       mddev_put(mddev);
-+
-+      if (kn)
-+              sysfs_unbreak_active_protection(kn);
-+
-       return rv;
- }
-@@ -5636,12 +5654,6 @@ static void md_kobj_release(struct kobject *ko)
- {
-       struct mddev *mddev = container_of(ko, struct mddev, kobj);
--      if (mddev->sysfs_state)
--              sysfs_put(mddev->sysfs_state);
--      if (mddev->sysfs_level)
--              sysfs_put(mddev->sysfs_level);
--
--      del_gendisk(mddev->gendisk);
-       put_disk(mddev->gendisk);
- }
-@@ -6531,8 +6543,9 @@ static int do_md_stop(struct mddev *mddev, int mode,
-               mddev->bitmap_info.offset = 0;
-               export_array(mddev);
--
-               md_clean(mddev);
-+              set_bit(MD_DELETED, &mddev->flags);
-+
-               if (mddev->hold_active == UNTIL_STOP)
-                       mddev->hold_active = 0;
-       }
-diff --git a/drivers/md/md.h b/drivers/md/md.h
-index 46995558d3bd..0a7c9122db50 100644
---- a/drivers/md/md.h
-+++ b/drivers/md/md.h
-@@ -589,11 +589,26 @@ static inline bool is_md_suspended(struct mddev *mddev)
- static inline int __must_check mddev_lock(struct mddev *mddev)
- {
--      return mutex_lock_interruptible(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_lock_interruptible(&mddev->reconfig_mutex);
-+
-+      /* MD_DELETED is set in do_md_stop with reconfig_mutex.
-+       * So check it here.
-+       */
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+
-+      return ret;
- }
- /* Sometimes we need to take the lock in a situation where
-  * failure due to interrupts is not acceptable.
-+ * It doesn't need to check MD_DELETED here, the owner which
-+ * holds the lock here can't be stopped. And all paths can't
-+ * call this function after do_md_stop.
-  */
- static inline void mddev_lock_nointr(struct mddev *mddev)
- {
-@@ -602,7 +617,14 @@ static inline void mddev_lock_nointr(struct mddev *mddev)
- static inline int mddev_trylock(struct mddev *mddev)
- {
--      return mutex_trylock(&mddev->reconfig_mutex);
-+      int ret;
-+
-+      ret = mutex_trylock(&mddev->reconfig_mutex);
-+      if (!ret && test_bit(MD_DELETED, &mddev->flags)) {
-+              ret = -ENODEV;
-+              mutex_unlock(&mddev->reconfig_mutex);
-+      }
-+      return ret;
- }
- extern void mddev_unlock(struct mddev *mddev);
--- 
-2.39.5
-
diff --git a/queue-6.6/md-don-t-clear-md_closing-until-mddev-is-freed.patch b/queue-6.6/md-don-t-clear-md_closing-until-mddev-is-freed.patch
deleted file mode 100644 (file)
index e14b19a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From c365a20552d7d7a9eb03cbefd91176c004e24340 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 15:31:07 +0800
-Subject: md: Don't clear MD_CLOSING until mddev is freed
-
-From: Xiao Ni <xni@redhat.com>
-
-[ Upstream commit 5f286f33553d600e6c2fb5a23dd6afcf99b3ebac ]
-
-UNTIL_STOP is used to avoid mddev is freed on the last close before adding
-disks to mddev. And it should be cleared when stopping an array which is
-mentioned in commit efeb53c0e572 ("md: Allow md devices to be created by
-name."). So reset ->hold_active to 0 in md_clean.
-
-And MD_CLOSING should be kept until mddev is freed to avoid reopen.
-
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Xiao Ni <xni@redhat.com>
-Link: https://lore.kernel.org/linux-raid/20250611073108.25463-3-xni@redhat.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/md/md.c | 16 ++++------------
- 1 file changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 8e3939c0d2ed..6a3b5b131111 100644
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -6265,15 +6265,10 @@ static void md_clean(struct mddev *mddev)
-       mddev->persistent = 0;
-       mddev->level = LEVEL_NONE;
-       mddev->clevel[0] = 0;
--      /*
--       * Don't clear MD_CLOSING, or mddev can be opened again.
--       * 'hold_active != 0' means mddev is still in the creation
--       * process and will be used later.
--       */
--      if (mddev->hold_active)
--              mddev->flags = 0;
--      else
--              mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-+      /* if UNTIL_STOP is set, it's cleared here */
-+      mddev->hold_active = 0;
-+      /* Don't clear MD_CLOSING, or mddev can be opened again. */
-+      mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
-       mddev->sb_flags = 0;
-       mddev->ro = MD_RDWR;
-       mddev->metadata_type[0] = 0;
-@@ -6545,9 +6540,6 @@ static int do_md_stop(struct mddev *mddev, int mode,
-               export_array(mddev);
-               md_clean(mddev);
-               set_bit(MD_DELETED, &mddev->flags);
--
--              if (mddev->hold_active == UNTIL_STOP)
--                      mddev->hold_active = 0;
-       }
-       md_new_event();
-       sysfs_notify_dirent_safe(mddev->sysfs_state);
--- 
-2.39.5
-
diff --git a/queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch b/queue-6.6/md-fix-create-on-open-mddev-lifetime-regression.patch
deleted file mode 100644 (file)
index fc2bb44..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 1df1fc845d221eb646539836dbf509eb96b41afd Mon Sep 17 00:00:00 2001
-From: Yu Kuai <yukuai3@huawei.com>
-Date: Wed, 30 Jul 2025 15:33:21 +0800
-Subject: md: fix create on open mddev lifetime regression
-
-From: Yu Kuai <yukuai3@huawei.com>
-
-commit 1df1fc845d221eb646539836dbf509eb96b41afd upstream.
-
-Commit 9e59d609763f ("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: syzbot+9921e319bd6168140b40@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0012.GAE@google.com/
-Reported-by: syzbot+fa3a12519f0d3fd4ec16@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/all/68894408.a00a0220.26d0e1.0013.GAE@google.com/
-Fixes: 9e59d609763f ("md: call del_gendisk in control path")
-Link: https://lore.kernel.org/linux-raid/20250730073321.2583158-1-yukuai1@huaweicloud.com
-Signed-off-by: Yu Kuai <yukuai3@huawei.com>
-Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
-Reviewed-by: Xiao Ni <xni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/md/md.c |    6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/md/md.c
-+++ b/drivers/md/md.c
-@@ -640,6 +640,12 @@ static void __mddev_put(struct mddev *md
-               return;
-       /*
-+       * If array is freed by stopping array, MD_DELETED is set by
-+       * do_md_stop(), MD_DELETED is still set here in case mddev is freed
-+       * directly by closing a mddev that is created by create_on_open.
-+       */
-+      set_bit(MD_DELETED, &mddev->flags);
-+      /*
-        * Call queue_work inside the spinlock so that flush_workqueue() after
-        * mddev_find will succeed in waiting for the work to be done.
-        */
index b4f04d03e987eb356ef178a4fd674dfef506054e..e96ee69f3d416ce71da0dd43227bd65eef59a572 100644 (file)
@@ -68,7 +68,6 @@ arm64-handle-kcov-__init-vs-inline-mismatches.patch
 smb-server-avoid-deadlock-when-linking-with-replacei.patch
 nvme-pci-try-function-level-reset-on-init-failure.patch
 gfs2-set-.migrate_folio-in-gfs2_-rgrp-meta-_aops.patch
-md-call-del_gendisk-in-control-path.patch
 loop-avoid-updating-block-size-under-exclusive-owner.patch
 udf-verify-partition-map-count.patch
 drbd-add-missing-kref_get-in-handle_write_conflicts.patch
@@ -77,7 +76,6 @@ better-lockdep-annotations-for-simple_recursive_remo.patch
 ata-libata-sata-disallow-changing-lpm-state-if-not-s.patch
 fs-ntfs3-add-sanity-check-for-file-name.patch
 fs-ntfs3-correctly-create-symlink-for-relative-path.patch
-md-don-t-clear-md_closing-until-mddev-is-freed.patch
 ext2-handle-fiemap-on-empty-files-to-prevent-einval.patch
 fix-locking-in-efi_secret_unlink.patch
 securityfs-don-t-pin-dentries-twice-once-is-enough.patch
@@ -329,5 +327,4 @@ tools-nolibc-fix-spelling-of-fd_setbitmask-in-fd_-macros.patch
 rdma-siw-fix-the-sendmsg-byte-count-in-siw_tcp_sendpages.patch
 hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch
 hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch
-md-fix-create-on-open-mddev-lifetime-regression.patch
 rcu-fix-racy-re-initialization-of-irq_work-causing-hangs.patch