From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E8413E51D4 for ; Tue, 30 Jun 2026 07:56:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782806207; cv=none; b=umz8uFQCPLPQ/aKQFGX60U4WluhMPQ5kHjXybTF7+B88an0dCd2b5cd2oNBtBDIUnbQPUZWfCPN1aIHRUiEFVOVX/e/U9O8JQfbb4Md7UB0aSBDgW/qCs5IfHDqvowm347zJmHtMcFZeRnsCnmOlU9OvKRzj0t2NiwF4x1pjioA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782806207; c=relaxed/simple; bh=NHGKYlW1z3Y4nDfaNAt30+5QScVY78fwL1TAANr1d2k=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=M1dnhY88KQgwQzyWHLxwHqXBR7WMLO1Hf2pSWn9RGk+W987d86kUnsa5jMX0m4tJjdecR22YtAtJq3CzCbdE35Fhs1c4bDFJQ57ql+5LlraS6GWX8Dk5ILxqYfr8r/6FElS7OBCCkhxv4JH+QUIxIovsZsMdAKlmd5+OgEt72AY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OjVkCSRO; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OjVkCSRO" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-49270caa5c0so32706505e9.3 for ; Tue, 30 Jun 2026 00:56:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782806204; x=1783411004; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=JcwI3L3/IZnl5azQAjtJ+Tb8ZlC5ITA8N1948cj+0U0=; b=OjVkCSROtmbjQTC/1c1fJcS62QBy7AVHDVhiclByqF+xqHE12XxvhqnTcX42CPlure 53tFlEwVd3zkAiM+Bo/XPei7ctZKOFdphw656km0+uwx1uTJOnTq2K7Nalub5oPqzVS6 5MXAyLF29NMhHKf94Pxs9V3JKNO1nPGzyXQ1NeZS5oERsx7DkggUI/eCaqPkYW0RFxr7 TxkPooWFkJWYHTnciEPDZqxsqC2YTuaMLqc8SU2HUhLx7S4TOuyvkQj1RpxveJjH6zcW T8xnWeT34Td+1UA0+uOGJMdJv5COCaMudEy/qTRUqWM/2ai9OFZjmRDK5xWIiBYB8PKE xFrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782806204; x=1783411004; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=JcwI3L3/IZnl5azQAjtJ+Tb8ZlC5ITA8N1948cj+0U0=; b=eIH7w1Cl12c+71131hkYOUN0CfD5TcmSuKdenYbszCA9GhUh2Mm2r5HxIscsLz1iQp iakz92Cmd3l5wQ2pqukLcMuuomYVVEZ3nYQMG1yYXwz4G20Q8VIwlRD4K0XLQxJ4A0/u 0Nbe0S4JZ+qiArccBtZmU8GEingQOd+u+sdsVPxIlYholpud3KqO0ITjiuzFD4b23J2s T5vrnTvkjIfZy8ZRfw12GKFk2ZlrbFZDP955rphDIVbZi47arWGWxnJGzpsRehUKpavk RA3mVu9M445ZNzU9XoKruPzzMdwbL510AgYCSZsj8X7uH2V28OuvBhSH51N3GfbrIl7Q iV7g== X-Forwarded-Encrypted: i=1; AFNElJ+ZjakJJ2NoLGIDEgjM0YrycAR0yBhHgq3emPvYDzS7z623s5RR6p5IbjT1hNzw9Vr+Q2OcfnX6f/YEb00=@vger.kernel.org X-Gm-Message-State: AOJu0YxHWGhNgTjLr5g84yzowHcjVt/vsJcAJ7ALHCm85MySsKQrVCAj QdZEtLuKDIdZVSEwlJrSf0KPIk20ca9VxOQw8feU+CtWbKxIUhS+Zs5N X-Gm-Gg: AfdE7cmmPqJtvte03/ucZR3Fa8O4K//yIblZAROag0iVk5SRNkFDfHHyaQEsH+kjzJl daAoKG6hQHLlIEOgryuj8QHPsiJP+EcnBAIOvETBHsQ/unbT8k/BuQHLj01UcvzC3F4QD3wbb96 VuMH9xb4LN0hC6YXDm0YNfJ+BUtVjy3McjYqaaUipMklWywxEdfGzRxYsYZ4IKxbN79HEhtd2yw azlZ6gf0m70Dtu5iKnl9ZJ/rdfL/cWFjIvilzLHM8975Yzunl5u3EayoOHGpKzuQbz/rlTMWpDU ufhHbnT5X1PMpgMFU46XlQo5Fq1GwKuWOkgcD61MEM7PyBoo2Vua9WOaG556YLv3rycthBxSR3H nOBytefAwA9oq2ioFIql2AYYPWbAUVF2o2087Xv6/IulwLEitug8u/fKAH7rAgsdrhJ8fb4p8bQ +K0iqzGPSxcSuocOTxspHRAAnMPWI5z1+c X-Received: by 2002:a05:600c:4745:b0:492:3316:4b34 with SMTP id 5b1f17b1804b1-493b827ea26mr36666665e9.2.1782806204318; Tue, 30 Jun 2026 00:56:44 -0700 (PDT) Received: from yocto.rz.uni-frankfurt.de ([141.2.113.146]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47566743895sm5216233f8f.25.2026.06.30.00.56.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jun 2026 00:56:43 -0700 (PDT) From: Abd-Alrhman Masalkhi To: song@kernel.org, yukuai@fygo.io, magiclinan@didiglobal.com, xiao@kernel.org Cc: linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org, Abd-Alrhman Masalkhi , sashiko-bot Subject: [PATCH] md: avoid modifying spares while the array is not suspended Date: Tue, 30 Jun 2026 07:56:40 +0000 Message-ID: <20260630075640.1081634-1-abd.masalkhi@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit remove_spares() and remove_and_add_spares() modify the array's rdev configuration. These operations are only safe after the array has been suspended. Today, md_start_sync() can call md_choose_sync_action() even when the array has not been suspended. As a result, 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 ensuring that remove_spares() and remove_and_add_spares() are only called after the array has been suspended, preventing concurrent rdev configuration changes while normal I/O is in progress. 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 --- drivers/md/md.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 66a41d482e59..c85ebb59535b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -10116,7 +10116,8 @@ static int remove_and_add_spares(struct mddev *mddev, return spares; } -static bool md_choose_sync_action(struct mddev *mddev, int *spares) +static bool md_choose_sync_action(struct mddev *mddev, int *spares, + bool array_suspended) { /* Check if reshape is in progress first. */ if (mddev->reshape_position != MaxSector) { @@ -10132,7 +10133,9 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares) /* Check if resync is in progress. */ if (mddev->resync_offset < MaxSector) { - remove_spares(mddev, NULL); + if (array_suspended) + remove_spares(mddev, NULL); + set_bit(MD_RECOVERY_SYNC, &mddev->recovery); clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); clear_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery); @@ -10144,7 +10147,11 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares) * also removed and re-added, to allow the personality to fail the * re-add. */ - *spares = remove_and_add_spares(mddev, NULL); + if (array_suspended) + *spares = remove_and_add_spares(mddev, NULL); + else + *spares = 0; + if (*spares || test_bit(MD_RECOVERY_LAZY_RECOVER, &mddev->recovery)) { clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); @@ -10189,11 +10196,12 @@ static void md_start_sync(struct work_struct *ws) * As we only add devices that are already in-sync, we can * activate the spares immediately. */ - remove_and_add_spares(mddev, NULL); + if (suspend) + remove_and_add_spares(mddev, NULL); goto not_running; } - if (!md_choose_sync_action(mddev, &spares)) + if (!md_choose_sync_action(mddev, &spares, suspend)) goto not_running; if (!mddev->pers->sync_request) -- 2.43.0