On Tue, 22 Sep 2026, syzbot wrote:

> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:    38872197cae2 Merge branch 'for-next/fixes' into for-kernelci
> git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git 
> for-kernelci
> console output: https://syzkaller.appspot.com/x/log.txt?x=116dd805580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=56ed23170c168d4c
> dashboard link: https://syzkaller.appspot.com/bug?extid=bdff1ecf726d2af66afd
> compiler:       Debian clang version 22.1.8 
> (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
> userspace arch: arm64
> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=14e8f805580000
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=17efe805580000
> 
> Downloadable assets:
> disk image: 
> https://storage.googleapis.com/syzbot-assets/c5963fdd6790/disk-38872197.raw.xz
> vmlinux: 
> https://storage.googleapis.com/syzbot-assets/a8c2cab00c45/vmlinux-38872197.xz
> kernel image: 
> https://storage.googleapis.com/syzbot-assets/bde15d173380/Image-38872197.gz.xz
> 
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: [email protected]

Hi

Here I'm sending a patch for this bug. Could you recheck it?

Mikulas



From: Mikulas Patocka <[email protected]>

When do_resume calls dm_table_get_mode(new_map), the call is done without
holding any locks (it only holds a reference to the md). It may be
possible that another concurrent ioctl on the same device will swap table
after dm_swap_table and before dm_table_get_mode. In this case,
dm_table_get_mode(new_map) reads freed memory.

This race condition was triggered by syzbot.

This commit fixes the race by reading mode of the new table before
dm_swap_table. Note that new_map is also passed to dm_ima_need_measure,
but this function doesn't attempt to dereference it, so this call should
be safe.

Note that this is not a security bug because only root can trigger it and
the commonly used tools such as lvm or cryptsetup do not call the ioctls
concurrently, so that they can't trigger it acceidentally.

Signed-off-by: Mikulas Patocka <[email protected]>
Reported-by: [email protected]
Cc: [email protected]

---
 drivers/md/dm-ioctl.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6/drivers/md/dm-ioctl.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-ioctl.c
+++ linux-2.6/drivers/md/dm-ioctl.c
@@ -1267,6 +1267,7 @@ static int do_resume(struct dm_ioctl *pa
        /* Do we need to load a new map ? */
        if (new_map) {
                sector_t old_size, new_size;
+               blk_mode_t new_map_mode;
 
                dm_ima_context_table_op(md, ima_context, DM_IMA_TABLE_SAVE);
                /* Suspend if it isn't already suspended */
@@ -1299,6 +1300,7 @@ static int do_resume(struct dm_ioctl *pa
                        }
                }
 
+               new_map_mode = dm_table_get_mode(new_map);
                old_size = dm_get_size(md);
                old_map = dm_swap_table(md, new_map);
                if (IS_ERR(old_map)) {
@@ -1314,7 +1316,7 @@ static int do_resume(struct dm_ioctl *pa
                if (old_size && new_size && old_size != new_size)
                        need_resize_uevent = true;
 
-               if (dm_table_get_mode(new_map) & BLK_OPEN_WRITE)
+               if (new_map_mode & BLK_OPEN_WRITE)
                        set_disk_ro(dm_disk(md), 0);
                else
                        set_disk_ro(dm_disk(md), 1);


Reply via email to