From nobody Sun May 19 01:15:17 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C81EA15B157; Wed, 27 Mar 2024 12:18:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711541897; cv=none; b=lHRVtY7ipHnNNkQvm+Nt5me0BbF5sfWZGZT29qUKb/5EekI0wV5I5oCfKCCxXmfGqszpGWMa+zmOeN3qumlL5fWW30WWXrWVsMWz4mqpuBpY0pUtvqCtwa0OeZI3JxBw8iAaVtUcEwn9Kn7jXFDfhQ0S6U5MEbKAID44YEprmdA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711541897; c=relaxed/simple; bh=lx1oGUOwPNUtykNgnCFmwoOfjMGkXSOfwPFZNw2X4Bk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=RsWy7aLJhH5xPOQEXrO2jOtRFqKGOA4MU40UhTKmFUFdQOSWasdijAXKugEeiB7NYYykS9al+nNcQIjGSITEQIsWyI+mjMGidfsBdWAFFjLHP3JjlOSuD64clBHJ0B0RCRjakrMWVy5KGccH6hSkt/lUUfj+5BGQHjzlRI06Vmo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=a4QSa9Bl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="a4QSa9Bl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84A75C43390; Wed, 27 Mar 2024 12:18:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711541897; bh=lx1oGUOwPNUtykNgnCFmwoOfjMGkXSOfwPFZNw2X4Bk=; h=From:To:Cc:Subject:Date:From; b=a4QSa9BlqWIiJlc5UKWXKY9m7qFGoYhf6P4RnC0uFbTBkR/9jSt3MbXtFJy8KUIxq 8wdTTJqvpiC5vnOR6DWtVTKmZ/5F3cFLtkAmSvQIyxdFK5hz4HOhxIgNzn6RgQ31ff abwIoyHziqGVGKioBU44uBCLHDYtdK0IBqaFlT2j803EtJx0xMGqU1QZdIDsAp3jI9 gy96nt2KhCwqj1tmYoeoyCCgS1H7wlMuy46VMlwjR5BYgW88AfWdrtivW2xsqx7EQr FvKvLK4Mhf24gn6HjlCqpGsmaVMPEw0qcRrklAycVdkAs7o6LKhjvdxpXmn5qwWoNo QAgiaSWGR9Iiw== From: Sasha Levin To: stable@vger.kernel.org, 2045gemini@gmail.com Cc: Yu Kuai , Song Liu , linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org Subject: FAILED: Patch "md/raid5: fix atomicity violation in raid5_cache_count" failed to apply to 5.10-stable tree Date: Wed, 27 Mar 2024 08:18:15 -0400 Message-ID: <20240327121815.2834185-1-sashal@kernel.org> 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 X-Patchwork-Hint: ignore X-stable: review Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The patch below does not apply to the 5.10-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . Thanks, Sasha Reviewed-by: Yu Kuai ------------------ original commit in Linus's tree ------------------ From dfd2bf436709b2bccb78c2dda550dde93700efa7 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han <2045gemini@gmail.com> Date: Fri, 12 Jan 2024 15:10:17 +0800 Subject: [PATCH] md/raid5: fix atomicity violation in raid5_cache_count In raid5_cache_count(): if (conf->max_nr_stripes < conf->min_nr_stripes) return 0; return conf->max_nr_stripes - conf->min_nr_stripes; The current check is ineffective, as the values could change immediately after being checked. In raid5_set_cache_size(): ... conf->min_nr_stripes =3D size; ... while (size > conf->max_nr_stripes) conf->min_nr_stripes =3D conf->max_nr_stripes; ... Due to intermediate value updates in raid5_set_cache_size(), concurrent execution of raid5_cache_count() and raid5_set_cache_size() may lead to inconsistent reads of conf->max_nr_stripes and conf->min_nr_stripes. The current checks are ineffective as values could change immediately after being checked, raising the risk of conf->min_nr_stripes exceeding conf->max_nr_stripes and potentially causing an integer overflow. This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations. The above possible bug is reported when our tool analyzes the source code of Linux 6.2. To resolve this issue, it is suggested to introduce local variables 'min_stripes' and 'max_stripes' in raid5_cache_count() to ensure the values remain stable throughout the check. Adding locks in raid5_cache_count() fails to resolve atomicity violations, as raid5_set_cache_size() may hold intermediate values of conf->min_nr_stripes while unlocked. With this patch applied, our tool no longer reports the bug, with the kernel configuration allyesconfig for x86_64. Due to the lack of associated hardware, we cannot test the patch in runtime testing, and just verify it according to the code logic. Fixes: edbe83ab4c27 ("md/raid5: allow the stripe_cache to grow and shrink.") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han <2045gemini@gmail.com> Reviewed-by: Yu Kuai Signed-off-by: Song Liu Link: https://lore.kernel.org/r/20240112071017.16313-1-2045gemini@gmail.com Signed-off-by: Song Liu --- drivers/md/raid5.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 14f2cf75abbd7..7ec445f49f1c3 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2412,7 +2412,7 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t= gfp) atomic_inc(&conf->active_stripes); =20 raid5_release_stripe(sh); - conf->max_nr_stripes++; + WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes + 1); return 1; } =20 @@ -2707,7 +2707,7 @@ static int drop_one_stripe(struct r5conf *conf) shrink_buffers(sh); free_stripe(conf->slab_cache, sh); atomic_dec(&conf->active_stripes); - conf->max_nr_stripes--; + WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes - 1); return 1; } =20 @@ -6820,7 +6820,7 @@ raid5_set_cache_size(struct mddev *mddev, int size) if (size <=3D 16 || size > 32768) return -EINVAL; =20 - conf->min_nr_stripes =3D size; + WRITE_ONCE(conf->min_nr_stripes, size); mutex_lock(&conf->cache_size_mutex); while (size < conf->max_nr_stripes && drop_one_stripe(conf)) @@ -6832,7 +6832,7 @@ raid5_set_cache_size(struct mddev *mddev, int size) mutex_lock(&conf->cache_size_mutex); while (size > conf->max_nr_stripes) if (!grow_one_stripe(conf, GFP_KERNEL)) { - conf->min_nr_stripes =3D conf->max_nr_stripes; + WRITE_ONCE(conf->min_nr_stripes, conf->max_nr_stripes); result =3D -ENOMEM; break; } @@ -7388,11 +7388,13 @@ static unsigned long raid5_cache_count(struct shrin= ker *shrink, struct shrink_control *sc) { struct r5conf *conf =3D shrink->private_data; + int max_stripes =3D READ_ONCE(conf->max_nr_stripes); + int min_stripes =3D READ_ONCE(conf->min_nr_stripes); =20 - if (conf->max_nr_stripes < conf->min_nr_stripes) + if (max_stripes < min_stripes) /* unlikely, but not impossible */ return 0; - return conf->max_nr_stripes - conf->min_nr_stripes; + return max_stripes - min_stripes; } =20 static struct r5conf *setup_conf(struct mddev *mddev) --=20 2.43.0