Archive-only list for patches
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Xiao Ni <xni@redhat.com>, Yu Kuai <yukuai3@huawei.com>,
	Sasha Levin <sashal@kernel.org>,
	song@kernel.org, linux-raid@vger.kernel.org
Subject: [PATCH AUTOSEL 6.6 19/23] md: Don't clear MD_CLOSING until mddev is freed
Date: Sun,  3 Aug 2025 17:20:26 -0400	[thread overview]
Message-ID: <20250803212031.3547641-19-sashal@kernel.org> (raw)
In-Reply-To: <20250803212031.3547641-1-sashal@kernel.org>

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>
---

LLM Generated explanations, may be completely bogus:

**Backport Status: YES**

This commit should be backported to stable kernel trees. Here's my
detailed analysis:

## Bug Fix Analysis

This commit fixes a race condition in the MD (Multiple Device) subsystem
where the MD_CLOSING flag could be cleared prematurely, allowing an
mddev to be reopened while it's in the process of being freed. This is a
clear use-after-free vulnerability.

## Key Issues Fixed

1. **Race condition with MD_CLOSING flag**: The old code would
   conditionally clear MD_CLOSING based on whether `hold_active` was
   set:
  ```c
  if (mddev->hold_active)
  mddev->flags = 0;  // This clears MD_CLOSING!
  else
  mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
  ```

2. **Improper hold_active handling**: The commit properly moves the
   clearing of `hold_active` from `do_md_stop()` into `md_clean()`,
   making the code cleaner and more predictable.

## Impact on Users

- **Security Impact**: This prevents a potential use-after-free
  vulnerability where an mddev could be reopened while being freed.
- **Stability Impact**: Prevents crashes or undefined behavior when
  racing between mddev close/free and reopen operations.
- **Data Integrity**: Could prevent corruption scenarios where
  operations are performed on a partially freed mddev structure.

## Code Changes Analysis

The changes are minimal and focused:
1. Removes the conditional logic that could clear MD_CLOSING
   inappropriately
2. Always preserves MD_CLOSING flag in `md_clean()` with: `mddev->flags
   &= BIT_ULL_MASK(MD_CLOSING)`
3. Moves `hold_active = 0` assignment from `do_md_stop()` to
   `md_clean()` for better code organization
4. Updates comments to clarify the behavior

## Stable Tree Criteria

✓ **Fixes a real bug**: Yes - race condition leading to potential use-
after-free
✓ **Small and contained**: Yes - only 15 lines changed in a single
function
✓ **No new features**: Correct - only fixes existing behavior
✓ **Minimal regression risk**: Yes - preserves existing semantics while
fixing the race
✓ **Important enough**: Yes - security/stability issue in core storage
subsystem

The commit message explicitly references commit efeb53c0e572 which
introduced the UNTIL_STOP mechanism, showing this is fixing a long-
standing issue in the MD subsystem's lifecycle management.

 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 2758c3ee2f56..60b49f7c74c2 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


  parent reply	other threads:[~2025-08-03 21:21 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-03 21:20 [PATCH AUTOSEL 6.6 01/23] hfs: fix general protection fault in hfs_find_init() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 02/23] hfs: fix slab-out-of-bounds in hfs_bnode_read() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 03/23] hfsplus: fix slab-out-of-bounds in hfsplus_bnode_read() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 04/23] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 05/23] hfsplus: don't use BUG_ON() in hfsplus_create_attributes_file() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 06/23] arm64: Handle KCOV __init vs inline mismatches Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 07/23] smb/server: avoid deadlock when linking with ReplaceIfExists Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 08/23] nvme-pci: try function level reset on init failure Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 09/23] gfs2: Set .migrate_folio in gfs2_{rgrp,meta}_aops Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 10/23] md: call del_gendisk in control path Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 11/23] loop: Avoid updating block size under exclusive owner Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 12/23] udf: Verify partition map count Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 13/23] drbd: add missing kref_get in handle_write_conflicts Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 14/23] hfs: fix not erasing deleted b-tree node issue Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 15/23] better lockdep annotations for simple_recursive_removal() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 16/23] ata: libata-sata: Disallow changing LPM state if not supported Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 17/23] fs/ntfs3: Add sanity check for file name Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 18/23] fs/ntfs3: correctly create symlink for relative path Sasha Levin
2025-08-03 21:20 ` Sasha Levin [this message]
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 20/23] ext2: Handle fiemap on empty files to prevent EINVAL Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 21/23] fix locking in efi_secret_unlink() Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 22/23] securityfs: don't pin dentries twice, once is enough Sasha Levin
2025-08-03 21:20 ` [PATCH AUTOSEL 6.6 23/23] tracefs: Add d_delete to remove negative dentries Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250803212031.3547641-19-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=song@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=xni@redhat.com \
    --cc=yukuai3@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox