Skip to contentSkip to conversation

FAILED: patch "[PATCH] dm: fix reading free memory in do_resume" failed to apply to 6.1-stable tree

PATCH New [email protected] 2 participants 2 messages Oct 12 – Oct 13

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x c9417c1c5269e2bd0570fbe53e4ec03a8d31f008
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026101223-profusely-doorframe-dbf3@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From c9417c1c5269e2bd0570fbe53e4ec03a8d31f008 Mon Sep 17 00:00:00 2001
From: Mikulas Patocka <[email protected]>
Date: Wed, 23 Sep 2026 12:40:16 +0200
Subject: [PATCH] dm: fix reading free memory in do_resume

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.

drivers/md/dm-ioctl.c +3 -1
index a005f124d706..8f945f0aeda5 100644
@@ -1273,6 +1273,7 @@ static int do_resume(struct dm_ioctl *param)
 	/* 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 */
@@ -1305,6 +1306,7 @@ static int do_resume(struct dm_ioctl *param)
 			}
 		}
 
+		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)) {
@@ -1320,7 +1322,7 @@ static int do_resume(struct dm_ioctl *param)
 		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);
maintainer
#1 lore raw

PATCH 1/1 dm: fix reading free memory in do_resume

From: Mikulas Patocka <[email protected]>

[ Upstream commit c9417c1c5269e2bd0570fbe53e4ec03a8d31f008 ]

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.

Reported-by [email protected]
[ sashal: Replaced blk_mode_t and BLK_OPEN_WRITE with fmode_t and FMODE_WRITE. ]
---
 drivers/md/dm-ioctl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/dm-ioctl.c +3 -1
index 4cfdd50e32d70..57d0bc1545b73 100644
@@ -1166,6 +1166,7 @@ static int do_resume(struct dm_ioctl *param)
 	/* Do we need to load a new map ? */
 	if (new_map) {
 		sector_t old_size, new_size;
+		fmode_t new_map_mode;
 
 		/* Suspend if it isn't already suspended */
 		if (param->flags & DM_SKIP_LOCKFS_FLAG)
@@ -1193,6 +1194,7 @@ static int do_resume(struct dm_ioctl *param)
 			}
 		}
 
+		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)) {
@@ -1205,7 +1207,7 @@ static int do_resume(struct dm_ioctl *param)
 		if (old_size && new_size && old_size != new_size)
 			need_resize_uevent = true;
 
-		if (dm_table_get_mode(new_map) & FMODE_WRITE)
+		if (new_map_mode & FMODE_WRITE)
 			set_disk_ro(dm_disk(md), 0);
 		else
 			set_disk_ro(dm_disk(md), 1);
Signature · 1 line
2.53.0