[dm-devel] Patch "dm thin: fix use-after-free crash in dm_sm_register_threshold_callback" has been added to the 5.18-stable tree

Sasha Levin sashal at kernel.org
Mon Aug 15 06:08:07 UTC 2022


This is a note to let you know that I've just added the patch titled

    dm thin: fix use-after-free crash in dm_sm_register_threshold_callback

to the 5.18-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     dm-thin-fix-use-after-free-crash-in-dm_sm_register_t.patch
and it can be found in the queue-5.18 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.



commit 185d3911adcea01b2082c14635a2a8071134384b
Author: Luo Meng <luomeng12 at huawei.com>
Date:   Thu Jul 14 19:28:25 2022 +0800

    dm thin: fix use-after-free crash in dm_sm_register_threshold_callback
    
    [ Upstream commit 3534e5a5ed2997ca1b00f44a0378a075bd05e8a3 ]
    
    Fault inject on pool metadata device reports:
      BUG: KASAN: use-after-free in dm_pool_register_metadata_threshold+0x40/0x80
      Read of size 8 at addr ffff8881b9d50068 by task dmsetup/950
    
      CPU: 7 PID: 950 Comm: dmsetup Tainted: G        W         5.19.0-rc6 #1
      Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
      Call Trace:
       <TASK>
       dump_stack_lvl+0x34/0x44
       print_address_description.constprop.0.cold+0xeb/0x3f4
       kasan_report.cold+0xe6/0x147
       dm_pool_register_metadata_threshold+0x40/0x80
       pool_ctr+0xa0a/0x1150
       dm_table_add_target+0x2c8/0x640
       table_load+0x1fd/0x430
       ctl_ioctl+0x2c4/0x5a0
       dm_ctl_ioctl+0xa/0x10
       __x64_sys_ioctl+0xb3/0xd0
       do_syscall_64+0x35/0x80
       entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    This can be easily reproduced using:
      echo offline > /sys/block/sda/device/state
      dd if=/dev/zero of=/dev/mapper/thin bs=4k count=10
      dmsetup load pool --table "0 20971520 thin-pool /dev/sda /dev/sdb 128 0 0"
    
    If a metadata commit fails, the transaction will be aborted and the
    metadata space maps will be destroyed. If a DM table reload then
    happens for this failed thin-pool, a use-after-free will occur in
    dm_sm_register_threshold_callback (called from
    dm_pool_register_metadata_threshold).
    
    Fix this by in dm_pool_register_metadata_threshold() by returning the
    -EINVAL error if the thin-pool is in fail mode. Also fail pool_ctr()
    with a new error message: "Error registering metadata threshold".
    
    Fixes: ac8c3f3df65e4 ("dm thin: generate event when metadata threshold passed")
    Cc: stable at vger.kernel.org
    Reported-by: Hulk Robot <hulkci at huawei.com>
    Signed-off-by: Luo Meng <luomeng12 at huawei.com>
    Signed-off-by: Mike Snitzer <snitzer at kernel.org>
    Signed-off-by: Sasha Levin <sashal at kernel.org>

diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index 2db7030aba00..a27395c8621f 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -2045,10 +2045,13 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
 					dm_sm_threshold_fn fn,
 					void *context)
 {
-	int r;
+	int r = -EINVAL;
 
 	pmd_write_lock_in_core(pmd);
-	r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
+	if (!pmd->fail_io) {
+		r = dm_sm_register_threshold_callback(pmd->metadata_sm,
+						      threshold, fn, context);
+	}
 	pmd_write_unlock(pmd);
 
 	return r;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 4d25d0e27031..53ac6ae870ac 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -3382,8 +3382,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
 						calc_metadata_threshold(pt),
 						metadata_low_callback,
 						pool);
-	if (r)
+	if (r) {
+		ti->error = "Error registering metadata threshold";
 		goto out_flags_changed;
+	}
 
 	dm_pool_register_pre_commit_callback(pool->pmd,
 					     metadata_pre_commit_callback, pool);



More information about the dm-devel mailing list