All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Sasha Levin" <sashal@kernel.org>, hexlabsecurity@proton.me
Cc: "Alasdair Kergon" <agk@redhat.com>,
	"Mike Snitzer" <snitzer@kernel.org>,
	dm-devel@lists.linux.dev
Subject: Re: Patch "dm array: validate array block headers on read" has been added to the 6.6-stable tree
Date: Thu, 22 Oct 2026 16:35:55 +0000	[thread overview]
Message-ID: <sashiko-outbox-181810@kernel.org> (raw)
In-Reply-To: <20261016180222.4058164-1-sashal@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] dm array: array_block_check() fails to validate value_size against info
--

commit 3c810b656c43751de89392b584e21daeb9a84fcd
Author: Sasha Levin <sashal@kernel.org>

Patch "dm array: validate array block headers on read" has been added to the 6.6-stable tree

This commit backports upstream commit 296578772308 to validate on-disk
array_block headers in array_block_check() by checking that value_size is
non-zero, max_entries matches calc_max_entries(), and nr_entries does not
exceed max_entries.

> diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c
> index 798c9c53a3435..fb65e82dab890 100644
> --- a/drivers/md/persistent-data/dm-array.c
> +++ b/drivers/md/persistent-data/dm-array.c
[ ... ]
> @@ -74,6 +83,26 @@ static int array_block_check(struct dm_block_validator *v,
>  		return -EILSEQ;
>  	}
>  
> +	nr_entries = le32_to_cpu(bh_le->nr_entries);
> +	max_entries = le32_to_cpu(bh_le->max_entries);
> +	value_size = le32_to_cpu(bh_le->value_size);
> +
> +	if (!value_size) {
> +		DMERR_LIMIT("%s failed: value_size is zero", __func__);
> +		return -EILSEQ;
> +	}
> +
> +	if (max_entries != calc_max_entries(value_size, size_of_block)) {
> +		DMERR_LIMIT("%s failed: max_entries %u invalid for value_size %u",
> +			    __func__, max_entries, value_size);
> +		return -EILSEQ;
> +	}
> +
> +	if (nr_entries > max_entries) {
> +		DMERR_LIMIT("%s failed: too many entries", __func__);
> +		return -EILSEQ;
> +	}
> +
>  	return 0;
>  }

[Severity: High]
Does validating max_entries and nr_entries only against the on-disk
bh_le->value_size in array_block_check() still allow out-of-bounds reads
in element_at() and trigger the BUG_ON() checks in fill_ablock() and
trim_ablock() when bh_le->value_size does not match info->value_type.size?

In drivers/md/persistent-data/dm-array.c, neither get_ablock() nor
__shadow_ablock() checks that the on-disk ab->value_size matches
info->value_type.size after dm_tm_read_lock() or dm_tm_shadow_block()
validates the block:

drivers/md/persistent-data/dm-array.c:get_ablock() {
	r = dm_tm_read_lock(info->btree_info.tm, b, &array_validator, block);
	if (r)
		return r;

	*ab = dm_block_data(*block);
	return 0;
}

However, element_at() computes entry offsets using info->value_type.size
rather than ab->value_size:

drivers/md/persistent-data/dm-array.c:element_at() {
	unsigned char *entry = (unsigned char *) (ab + 1);

	entry += index * info->value_type.size;

	return entry;
}

If a corrupted or crafted on-disk array_block header has a smaller
value_size than info->value_type.size (for example, value_size = 1,
max_entries = 4072, and nr_entries = 4072 in a 4096-byte block when
info->value_type.size is 8 in dm-cache or dm-bitset), array_block_check()
succeeds. Callers that iterate up to le32_to_cpu(ab->nr_entries), such as
dm_array_cursor_next() and dm_array_cursor_get_value() (via
dm_cache_load_mappings()), walk_ablock(), on_entries() (via
inc_ablock_entries() and dec_ablock_entries()), and trim_ablock(), will
still advance index up to 4071 while element_at() strides by
info->value_type.size, reading past the end of the dm-bufio block buffer.

Conversely, if on-disk bh_le->value_size is larger than
info->value_type.size, array_block_check() accepts a smaller
ab->max_entries than the capacity computed from info->value_type.size in
dm_array_resize() -> array_resize(). When array_resize() passes new_nr up
to resize->max_entries into fill_ablock() or trim_ablock(), it can still
trigger BUG_ON(new_nr > le32_to_cpu(ab->max_entries)):

drivers/md/persistent-data/dm-array.c:fill_ablock() {
	uint32_t nr_entries, delta, i;
	struct dm_btree_value_type *vt = &info->value_type;

	BUG_ON(new_nr > le32_to_cpu(ab->max_entries));
	BUG_ON(new_nr < le32_to_cpu(ab->nr_entries));
	...
}

Should get_ablock() and __shadow_ablock() also verify that
le32_to_cpu((*ab)->value_size) == info->value_type.size before using or
incrementing the block entries?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261016180222.4058164-1-sashal@kernel.org?part=1

      reply	other threads:[~2026-10-22 16:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 18:02 Patch "dm array: validate array block headers on read" has been added to the 6.6-stable tree Sasha Levin
2026-10-22 16:35 ` 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-181810@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agk@redhat.com \
    --cc=dm-devel@lists.linux.dev \
    --cc=hexlabsecurity@proton.me \
    --cc=sashal@kernel.org \
    --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 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.