Linux Device Mapper development
 help / color / mirror / Atom feed
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

      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