|
Coly Li |
ec13f5 |
From 3534e5a5ed2997ca1b00f44a0378a075bd05e8a3 Mon Sep 17 00:00:00 2001
|
|
Coly Li |
ec13f5 |
From: Luo Meng <luomeng12@huawei.com>
|
|
Coly Li |
ec13f5 |
Date: Thu, 14 Jul 2022 19:28:25 +0800
|
|
Coly Li |
ec13f5 |
Subject: [PATCH] dm thin: fix use-after-free crash in
|
|
Coly Li |
ec13f5 |
dm_sm_register_threshold_callback
|
|
Coly Li |
ec13f5 |
Git-commit: 3534e5a5ed2997ca1b00f44a0378a075bd05e8a3
|
|
Coly Li |
ec13f5 |
Patch-mainline: v6.0-rc1
|
|
Coly Li |
ec13f5 |
References: git-fixes
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
Fault inject on pool metadata device reports:
|
|
Coly Li |
ec13f5 |
BUG: KASAN: use-after-free in dm_pool_register_metadata_threshold+0x40/0x80
|
|
Coly Li |
ec13f5 |
Read of size 8 at addr ffff8881b9d50068 by task dmsetup/950
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
CPU: 7 PID: 950 Comm: dmsetup Tainted: G W 5.19.0-rc6 #1
|
|
Coly Li |
ec13f5 |
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
|
|
Coly Li |
ec13f5 |
Call Trace:
|
|
Coly Li |
ec13f5 |
<TASK>
|
|
Coly Li |
ec13f5 |
dump_stack_lvl+0x34/0x44
|
|
Coly Li |
ec13f5 |
print_address_description.constprop.0.cold+0xeb/0x3f4
|
|
Coly Li |
ec13f5 |
kasan_report.cold+0xe6/0x147
|
|
Coly Li |
ec13f5 |
dm_pool_register_metadata_threshold+0x40/0x80
|
|
Coly Li |
ec13f5 |
pool_ctr+0xa0a/0x1150
|
|
Coly Li |
ec13f5 |
dm_table_add_target+0x2c8/0x640
|
|
Coly Li |
ec13f5 |
table_load+0x1fd/0x430
|
|
Coly Li |
ec13f5 |
ctl_ioctl+0x2c4/0x5a0
|
|
Coly Li |
ec13f5 |
dm_ctl_ioctl+0xa/0x10
|
|
Coly Li |
ec13f5 |
__x64_sys_ioctl+0xb3/0xd0
|
|
Coly Li |
ec13f5 |
do_syscall_64+0x35/0x80
|
|
Coly Li |
ec13f5 |
entry_SYSCALL_64_after_hwframe+0x46/0xb0
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
This can be easily reproduced using:
|
|
Coly Li |
ec13f5 |
echo offline > /sys/block/sda/device/state
|
|
Coly Li |
ec13f5 |
dd if=/dev/zero of=/dev/mapper/thin bs=4k count=10
|
|
Coly Li |
ec13f5 |
dmsetup load pool --table "0 20971520 thin-pool /dev/sda /dev/sdb 128 0 0"
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
If a metadata commit fails, the transaction will be aborted and the
|
|
Coly Li |
ec13f5 |
metadata space maps will be destroyed. If a DM table reload then
|
|
Coly Li |
ec13f5 |
happens for this failed thin-pool, a use-after-free will occur in
|
|
Coly Li |
ec13f5 |
dm_sm_register_threshold_callback (called from
|
|
Coly Li |
ec13f5 |
dm_pool_register_metadata_threshold).
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
Fix this by in dm_pool_register_metadata_threshold() by returning the
|
|
Coly Li |
ec13f5 |
-EINVAL error if the thin-pool is in fail mode. Also fail pool_ctr()
|
|
Coly Li |
ec13f5 |
with a new error message: "Error registering metadata threshold".
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
Fixes: ac8c3f3df65e4 ("dm thin: generate event when metadata threshold passed")
|
|
Coly Li |
ec13f5 |
Cc: stable@vger.kernel.org
|
|
Coly Li |
ec13f5 |
Reported-by: Hulk Robot <hulkci@huawei.com>
|
|
Coly Li |
ec13f5 |
Signed-off-by: Luo Meng <luomeng12@huawei.com>
|
|
Coly Li |
ec13f5 |
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
|
|
Coly Li |
ec13f5 |
Signed-off-by: Coly Li <colyli@suse.de>
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
---
|
|
Coly Li |
ec13f5 |
drivers/md/dm-thin-metadata.c | 7 +++++--
|
|
Coly Li |
ec13f5 |
drivers/md/dm-thin.c | 4 +++-
|
|
Coly Li |
ec13f5 |
2 files changed, 8 insertions(+), 3 deletions(-)
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
|
|
Coly Li |
ec13f5 |
index 2db7030aba00..a27395c8621f 100644
|
|
Coly Li |
ec13f5 |
--- a/drivers/md/dm-thin-metadata.c
|
|
Coly Li |
ec13f5 |
+++ b/drivers/md/dm-thin-metadata.c
|
|
Coly Li |
ec13f5 |
@@ -2045,10 +2045,13 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
|
|
Coly Li |
ec13f5 |
dm_sm_threshold_fn fn,
|
|
Coly Li |
ec13f5 |
void *context)
|
|
Coly Li |
ec13f5 |
{
|
|
Coly Li |
ec13f5 |
- int r;
|
|
Coly Li |
ec13f5 |
+ int r = -EINVAL;
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
pmd_write_lock_in_core(pmd);
|
|
Coly Li |
ec13f5 |
- r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
|
|
Coly Li |
ec13f5 |
+ if (!pmd->fail_io) {
|
|
Coly Li |
ec13f5 |
+ r = dm_sm_register_threshold_callback(pmd->metadata_sm,
|
|
Coly Li |
ec13f5 |
+ threshold, fn, context);
|
|
Coly Li |
ec13f5 |
+ }
|
|
Coly Li |
ec13f5 |
pmd_write_unlock(pmd);
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
return r;
|
|
Coly Li |
ec13f5 |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
|
|
Coly Li |
ec13f5 |
index 84c083f76673..e76c96c760a9 100644
|
|
Coly Li |
ec13f5 |
--- a/drivers/md/dm-thin.c
|
|
Coly Li |
ec13f5 |
+++ b/drivers/md/dm-thin.c
|
|
Coly Li |
ec13f5 |
@@ -3375,8 +3375,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
|
Coly Li |
ec13f5 |
calc_metadata_threshold(pt),
|
|
Coly Li |
ec13f5 |
metadata_low_callback,
|
|
Coly Li |
ec13f5 |
pool);
|
|
Coly Li |
ec13f5 |
- if (r)
|
|
Coly Li |
ec13f5 |
+ if (r) {
|
|
Coly Li |
ec13f5 |
+ ti->error = "Error registering metadata threshold";
|
|
Coly Li |
ec13f5 |
goto out_flags_changed;
|
|
Coly Li |
ec13f5 |
+ }
|
|
Coly Li |
ec13f5 |
|
|
Coly Li |
ec13f5 |
dm_pool_register_pre_commit_callback(pool->pmd,
|
|
Coly Li |
ec13f5 |
metadata_pre_commit_callback, pool);
|
|
Coly Li |
ec13f5 |
--
|
|
Coly Li |
ec13f5 |
2.35.3
|
|
Coly Li |
ec13f5 |
|