From: Jay Vadayath <jay@artiphishell.com>
To: 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, linux-kernel@vger.kernel.org,
Jay Vadayath <jay@artiphishell.com>
Subject: [PATCH] dm-raid: bound array_position before indexing failed_devices
Date: Thu, 22 Oct 2026 11:19:34 -0700 [thread overview]
Message-ID: <20261022181934.35685-1-jay@artiphishell.com> (raw)
super_init_validation() reads role = le32_to_cpu(sb2->array_position)
out of an on-disk dm_raid_superblock and then uses it as a bit index into
the failed_devices bitmap via test_bit(role, (void *)failed_devices).
failed_devices is a uint64_t[DISKS_ARRAY_ELEMS] (DISKS_ARRAY_ELEMS == 4,
i.e. 256 bits) living on the stack. The only guard is role < 0, so any
on-disk array_position >= 256 makes test_bit() read past the end of the
stack array (array_position == 256 reads failed_devices[4], 8 bytes past
the object). For a raid1 set the role != raid_disk reorder branch falls
through to the same test_bit().
A crafted dm-raid superblock therefore causes a stack out-of-bounds read
during table load. Reachable by anyone able to issue a dmsetup create
with attacker-controlled metadata (CAP_SYS_ADMIN in the target
namespace); the crash fires in the constructor / analyse_superblocks
path, before any md_run or array sizing.
BUG: KASAN: stack-out-of-bounds in super_validate+0x1cd0/0x3390
Read of size 8 at addr ffff888007b17828 by task poc/152
Call Trace:
dump_stack_lvl+0x64/0x80
print_report+0xd0/0x630
kasan_report+0xe5/0x120
kasan_check_range+0x105/0x1b0
super_validate+0x1cd0/0x3390 (super_init_validation, inlined)
raid_ctr+0x2c4b/0xa0f0
dm_table_add_target+0x66f/0xf80
table_load+0x2ee/0x780
ctl_ioctl+0x362/0x9f0
dm_ctl_ioctl+0x9/0x10
__x64_sys_ioctl+0x134/0x1c0
do_syscall_64+0xe2/0x4b0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
role is a device position that must refer to an actual member of the
array, so reject anything outside [0, rs->raid_disks) instead of only the
negative case. rs->raid_disks is always <= the 256-bit capacity of
failed_devices, so this both closes the out-of-bounds access and matches
the intended semantics.
This bug was discovered by Artiphishell's vTriage pipeline, which
generated a crafted raid1 superblock (magic "DmRd", compat_features=1,
num_devices=2, array_position=256, level=1) and a dmsetup-create
reproducer that reliably triggers the KASAN report on an unpatched kernel
(the precursor DMINFO "raid device #256 now at position #0" is visible in
the serial log just before the splat). The fix below was drafted with the
Claude coding assistant; a userspace reproducer is available on request.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jay Vadayath <jay@artiphishell.com>
---
drivers/md/dm-raid.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 8f5a5e1342a9..d497d7c68596 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;
if (role != r->raid_disk) {
--
2.51.2
next reply other threads:[~2026-10-22 18:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 18:19 Jay Vadayath [this message]
2026-10-22 18:31 ` [PATCH] dm-raid: bound array_position before indexing failed_devices 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=20261022181934.35685-1-jay@artiphishell.com \
--to=jay@artiphishell.com \
--cc=agk@redhat.com \
--cc=bmarzins@redhat.com \
--cc=dm-devel@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=mpatocka@redhat.com \
--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.