From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F116337E5D1; Sat, 12 Sep 2026 12:37:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789216668; cv=none; b=Dz58TJ694VSJIVyLPiiZsEqse6WWA5wrtlZk1IUkevS9qX3mEXBFgiEHUbBxqZ2ay4FsLGivu1vgrI/PmNmw5vF/jW6Oio3V8NOY/RKdMdX2QDIKJHjA17SDO7OHHZBW6+YHxBEZCL347k3W/P8BarYIxPSJcmya47InZDJvpJA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789216668; c=relaxed/simple; bh=jFmlKHEiPHzO2D6fpgcuib9QGV/MBLnIMibJivwRwZ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KAWWt91mBkxvuJ7MmWrn+FHC8GDN6irR+Q5SJunjH8J/heWORxNaEtizmBA0A/iAFNNXIzPgQjObtsh6PKnN79rkMPASybO4ebc+5UND3aQgRGe3SNl7h/Ibcv5t9Wc21rMgebxx5EaT8vQaejBi/298kZwLLvyc/ieHVLfR3IY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=UBTm4ZAS; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="UBTm4ZAS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D76821F00893; Sat, 12 Sep 2026 12:37:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1789216666; bh=AD0hmiafu6AZjKmL8nVojeuDuErYkjLaHrmryzrEqjs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UBTm4ZASlovy6A3bNM2hCZp2CaeXipFv9EvDm7/ZS6fZS+Dawrgrw8J9mqs79jh0Z LjAPdz92KWrLUo3+k7PHhx9hbNLUguQp6LkSIC2mxXVXVvw+zwx6HE3a1CygZdYsoG vCTwaPe6lwPvmP95yMMkR5w5enhqXDXAH0P4Pg8M= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, sashiko-bot , Abd-Alrhman Masalkhi , Yu Kuai , Sasha Levin Subject: [PATCH 6.12 0746/1376] md: recheck spare changes before starting sync Date: Sat, 12 Sep 2026 08:52:52 +0200 Message-ID: <20260912065624.170376735@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260912065607.535295758@linuxfoundation.org> References: <20260912065607.535295758@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Abd-Alrhman Masalkhi [ Upstream commit c7d34d17ea43ebc86b45d439ebb435e11ca44bca ] remove_spares() and remove_and_add_spares() modify the array's rdev configuration. These operations are only safe after the array has been suspended. md_start_sync() checks whether spare configuration changes are needed before taking reconfig_mutex. However, the rdev state can change before the mutex is acquired, so the initial check can become stale. In that case, md_choose_sync_action() may remove or replace rdevs while normal I/O is still accessing them. The race can occur as follows: raid10d Worker Normal IO ____________ _______________________ ______________________ raid10_write_request() wait_blocked_dev() set Blocked set Faulty Skip Faulty rdev rrdev->nr_pending++ .repl_bio = bio removeable_rdev = false . array not suspended . lock mddev goto err_handle lock mddev (wait) . update sb . clear Blocked . . unlock mddev . lock mddev (acquires) remove_spares() removeable_rdev = true raid10_remove_disk() rdev = replacement replacement = NULL rdev_dec_pending(NULL) unlock mddev (NULL)->nr_pending-- In this case, rdev_dec_pending() is called with a NULL pointer, resulting in a NULL pointer dereference when attempting to decrement nr_pending. Fix this by suspending the array when spare configuration changes are needed, including for non-read-write arrays, and checking again after taking reconfig_mutex. If the array was not already suspended and a change is now needed, release the mutex, suspend the array, and reacquire the mutex before continuing. Fixes: bc08041b32ab ("md: suspend array in md_start_sync() if array need reconfiguration") Reported-by: sashiko-bot Closes: https://sashiko.dev/#/patchset/20260628142420.1051027-1-abd.masalkhi@gmail.com?part=3 Signed-off-by: Abd-Alrhman Masalkhi Reviewed-by: Yu Kuai Link: https://patch.msgid.link/20260708112003.474537-1-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai Signed-off-by: Sasha Levin --- drivers/md/md.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 889711a24b1cb..3e683b9626df5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9583,13 +9583,25 @@ static void md_start_sync(struct work_struct *ws) * If reshape is still in progress, spares won't be added or removed * from conf until reshape is done. */ - if (mddev->reshape_position == MaxSector && + if ((mddev->reshape_position == MaxSector || !md_is_rdwr(mddev)) && md_spares_need_change(mddev)) { suspend = true; mddev_suspend(mddev, false); } mddev_lock_nointr(mddev); + + /* + * The spare configuration can change before reconfig_mutex is acquired. + * Recheck while holding the lock and suspend if needed. + */ + if (!suspend && (mddev->reshape_position == MaxSector || !md_is_rdwr(mddev)) && + md_spares_need_change(mddev)) { + mddev_unlock(mddev); + mddev_suspend_and_lock_nointr(mddev); + suspend = true; + } + if (!md_is_rdwr(mddev)) { /* * On a read-only array we can: -- 2.53.0