From: sashiko-bot@kernel.org
To: "Hiroshi Nishida" <nishidafmly@gmail.com>
Cc: linux-raid@vger.kernel.org, yukuai@fygo.io
Subject: Re: [PATCH 1/2] md: change chunk_sectors and stripe cache counts to unsigned int
Date: Fri, 10 Jul 2026 15:44:37 +0000 [thread overview]
Message-ID: <20260710154437.DFAF91F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260710132329.7273-2-nishidafmly@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Lockless read race on total_cached evaluates to a negative value, triggering unsigned promotion and false cache pressure signals.
Pre-existing issues:
- [Critical] The calculation of total sectors per chunk stripe (chunk size multiplied by data disks) is performed using 32-bit arithmetic, which can overflow. This leads to a divide-by-zero kernel panic or incorrect boundary math if a maliciously large chunk size is provided.
--
--- Patch [1]: [PATCH 1/2] md: change chunk_sectors and stripe cache counts to unsigned int ---
commit 6fa5b599e890f5ca04407ab1005af1cc096d709e
Author: Hiroshi Nishida <nishidafmly@gmail.com>
md: change chunk_sectors and stripe cache counts to unsigned int
This commit changes various chunk and stripe counts from signed to
unsigned int in the md/raid5 subsystem to prevent negative values.
It allows the compiler to optimize division and modulo operations by
power-of-two chunk sizes to right shifts in the hot I/O path.
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 0c5c9fb0606ee..28828e083c2b3 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
[ ... ]
> @@ -7929,7 +7929,7 @@ static int raid5_run(struct mddev *mddev)
> sector_t here_new, here_old;
> int old_disks;
> int max_degraded = (mddev->level == 6 ? 2 : 1);
> - int chunk_sectors;
> + unsigned int chunk_sectors;
> int new_data_disks;
[Severity: Critical]
This isn't a bug introduced by this patch, but changing the types to
unsigned int fails to resolve an underlying 32-bit wrapping regression.
Does this code overflow when calculating total sectors per chunk stripe?
In raid5_run(), if a maliciously crafted RAID superblock sets chunksize
to 0x08000000 (64 GiB) and raid_disks to 33, the multiplication
(chunk_sectors * new_data_disks) evaluates to 0x08000000 * 32.
This wraps to 0 in 32-bit arithmetic, which is then passed to sector_div():
if (sector_div(here_new, chunk_sectors * new_data_disks)) {
This triggers a divide-by-zero panic. A similar issue occurs in
make_discard_request() where DIV_ROUND_UP_SECTOR_T() is called with a
wrapped stripe_sectors value.
> diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
> index cb5feae04db27..5cd9d0f36b6e0 100644
> --- a/drivers/md/raid5.h
> +++ b/drivers/md/raid5.h
[ ... ]
> @@ -572,12 +572,12 @@ struct r5conf {
> /* only protect corresponding hash list and inactive_list */
> spinlock_t hash_locks[NR_STRIPE_HASH_LOCKS];
> struct mddev *mddev;
> - int chunk_sectors;
> + unsigned int chunk_sectors;
> int level, algorithm, rmw_level;
> int max_degraded;
> int raid_disks;
> - int max_nr_stripes;
> - int min_nr_stripes;
> + unsigned int max_nr_stripes;
> + unsigned int min_nr_stripes;
[Severity: Medium]
Does changing min_nr_stripes to unsigned int introduce a spurious cache
flush regression due to type promotion?
In drivers/md/raid5-cache.c:r5c_do_reclaim(), total_cached can evaluate
to -1 if r5c_finish_stripe_write_out() concurrently decrements
r5c_flushing_partial_stripes and r5c_cached_partial_stripes during a
lockless read.
Since min_nr_stripes is now unsigned, the -1 is promoted to UINT_MAX in
this condition:
if (total_cached > conf->min_nr_stripes * 3 / 4 ||
This makes the cache pressure check spuriously evaluate to true, leading
to unnecessary CPU wakeups and a performance regression during writeback
workloads.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260710132329.7273-1-nishidafmly@gmail.com?part=1
next prev parent reply other threads:[~2026-07-10 15:44 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 13:23 [PATCH 0/2] md: widen size/count types for large arrays Hiroshi Nishida
2026-07-10 13:23 ` [PATCH 1/2] md: change chunk_sectors and stripe cache counts to unsigned int Hiroshi Nishida
2026-07-10 15:44 ` sashiko-bot [this message]
2026-07-10 13:23 ` [PATCH 2/2] md: widen badblock sectors param from int to sector_t Hiroshi Nishida
2026-07-10 13:40 ` sashiko-bot
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=20260710154437.DFAF91F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-raid@vger.kernel.org \
--cc=nishidafmly@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yukuai@fygo.io \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.