From: sashiko-bot@kernel.org
To: "Jay Vadayath" <jay@artiphishell.com>,
"Alasdair Kergon" <agk@redhat.com>,
"Mike Snitzer" <snitzer@kernel.org>,
"Mikulas Patocka" <mpatocka@redhat.com>,
"Benjamin Marzinski" <bmarzins@redhat.com>
Cc: dm-devel@lists.linux.dev
Subject: Re: [PATCH] dm-raid: bound array_position before indexing failed_devices
Date: Thu, 22 Oct 2026 18:31:42 +0000 [thread overview]
Message-ID: <sashiko-outbox-181921@kernel.org> (raw)
In-Reply-To: <20261022181934.35685-1-jay@artiphishell.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] dm-raid: wrong role bound and continue bypass in super_init_validation()
--
commit 46b04454594856163e75cd4dccd01fd7ff3efea6
Author: Jay Vadayath <jay@artiphishell.com>
dm-raid: bound array_position before indexing failed_devices
This commit bounds the on-disk array_position (role) by rs->raid_disks in
super_init_validation() before using it as a bit index into the on-stack
failed_devices bitmap.
> diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
> index ac019a0f5a929..b973181bdce24 100644
> --- a/drivers/md/dm-raid.c
> +++ b/drivers/md/dm-raid.c
> @@ -2420,7 +2420,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev)
> */
> if (!test_bit(FirstUse, &r->flags) && (r->raid_disk >= 0)) {
> role = le32_to_cpu(sb2->array_position);
> - if (role < 0)
> + /* Bound @role before it indexes the failed_devices stack bitmap. */
> + if (role < 0 || role >= rs->raid_disks)
> continue;
[Severity: High]
Does using continue when role >= rs->raid_disks in
drivers/md/dm-raid.c:super_init_validation() introduce two regressions during
table load (dm_ctl_ioctl() -> table_load() -> dm_table_add_target() ->
raid_ctr() -> analyse_superblocks() -> super_validate() ->
super_init_validation())?
First, the commit message states that this change rejects anything outside
[0, rs->raid_disks), but executing continue only skips the remainder of the
per-rdev loop body and allows super_init_validation() to return 0:
drivers/md/dm-raid.c:super_init_validation() {
...
if (!test_bit(FirstUse, &r->flags) && (r->raid_disk >= 0)) {
role = le32_to_cpu(sb2->array_position);
/* Bound @role before it indexes the failed_devices stack bitmap. */
if (role < 0 || role >= rs->raid_disks)
continue;
if (role != r->raid_disk) {
...
} else if (!(rs_is_raid10(rs) && rt_is_raid0(rs->raid_type)) &&
!(rs_is_raid0(rs) && rt_is_raid10(rs->raid_type)) &&
!rt_is_raid1(rs->raid_type)) {
rs->ti->error = "Cannot change device positions in raid set";
return -EINVAL;
}
...
}
Because r->raid_disk is in [0, rs->raid_disks), any device with
role >= rs->raid_disks has role != r->raid_disk. Previously, on raid levels
that forbid device reordering (such as raid4/5/6 or raid10 far/offset), a
device with role in [rs->raid_disks, 255] entered the role != r->raid_disk
block and failed validation with return -EINVAL. With this continue, shouldn't
an out-of-bounds role return -EINVAL instead of silently bypassing both the
device reordering check and the failed_devices check?
Second, is rs->raid_disks the right upper bound for role here? In
super_init_validation(), role is the device's previous position in the
on-disk array of size mddev->raid_disks (le32_to_cpu(sb->num_devices)), and
failed_devices is indexed by that previous role, whereas rs->raid_disks is
the device count of the newly loaded table.
dm-raid allows loading tables with rs->raid_disks < mddev->raid_disks when
removing legs from a raid1 array without delta_disks or when removing mirror
copies from a raid10_near array:
drivers/md/dm-raid.c:rs_prepare_reshape() {
if (rs_is_raid10(rs)) {
if (rs->raid_disks != mddev->raid_disks &&
__is_raid10_near(mddev->layout) &&
rs->raid10_copies &&
rs->raid10_copies != __raid10_near_copies(mddev->layout)) {
...
__reorder_raid_disk_indexes(rs);
...
}
...
} else if (rs_is_raid1(rs)) {
if (rs->delta_disks) {
...
} else {
/* Process raid1 without delta_disks */
mddev->raid_disks = rs->raid_disks;
reshape = false;
}
}
}
When a non-trailing leg or mirror copy is removed so that rs->raid_disks <
mddev->raid_disks (for example, removing leg 0 from a 3-disk raid1 array so
old device 2 moves to r->raid_disk = 1 with rs->raid_disks = 2, or reducing a
6-disk 3-copy raid10_near set to a 4-disk 2-copy set so old device 4 moves to
r->raid_disk = 3 with rs->raid_disks = 4), surviving devices legitimately
have rs->raid_disks <= role < mddev->raid_disks.
If role >= rs->raid_disks takes the continue branch, won't
super_init_validation() skip updating sb2->array_position for raid10_near and
skip testing failed_devices to set Faulty on a returning failed device,
preventing super_validate() from clearing In_sync and resetting
recovery_offset to 0?
>
> if (role != r->raid_disk) {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261022181934.35685-1-jay@artiphishell.com?part=1
prev parent reply other threads:[~2026-10-22 18:31 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 18:19 [PATCH] dm-raid: bound array_position before indexing failed_devices Jay Vadayath
2026-10-22 18:31 ` sashiko-bot [this message]
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=sashiko-outbox-181921@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agk@redhat.com \
--cc=bmarzins@redhat.com \
--cc=dm-devel@lists.linux.dev \
--cc=jay@artiphishell.com \
--cc=mpatocka@redhat.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=snitzer@kernel.org \
/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