401 Star 1.4K Fork 1.3K

GVPopenEuler / kernel

 / 详情

ubi异常路径和debug接口访问触发UAF

已完成
缺陷
创建于  
2023-02-06 11:23

【标题描述】ubi异常路径和debug接口访问触发UAF
【环境信息】
NA
软件信息:
OLK-5.19
【问题复现步骤】
CONFIG_KASAN=y

  1. Apply diff and compile kernel
  2. run test.sh
  3. Execute 'cat /sys/kernel/debug/ubi/ubi0/detailed_erase_block_info' in 3 seconds after kernel printing message "make err"
    出现概率(是否必现,概率性错误)必现
    【预期结果】
    KASAN panic
    【实际结果】
[  126.767164] make err
[  126.768457] ubi0 error: __erase_worker.cold [ubi]: failed to erase PEB 0, error -5
[  126.772110] free ffff8881034a8ae0
[  128.394871] eraseblk_count_seq_show: access ffff8881034a8ae0
[  129.823313] freed
[  133.404360] ==================================================================
[  133.407544] BUG: KASAN: use-after-free in eraseblk_count_seq_show+0xd5/0x180 [ubi]
[  133.408642] Read of size 4 at addr ffff8881034a8af8 by task cat/1627
[  133.409254] 
[  133.410097] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc34
[  133.411305] Call Trace:
[  133.411567]  <TASK>
[  133.411790]  ? dump_stack_lvl+0x73/0x9f
[  133.412198]  ? print_report.cold+0x100/0xa3f
[  133.412631]  ? _raw_spin_lock_irqsave+0xcd/0x160
[  133.413100]  ? eraseblk_count_seq_show+0xd5/0x180 [ubi]
[  133.413932]  ? kasan_report+0xbf/0x130
[  133.414335]  ? eraseblk_count_seq_show+0xd5/0x180 [ubi]
[  133.415175]  ? __asan_load4+0x77/0x120
[  133.415556]  ? eraseblk_count_seq_show+0xd5/0x180 [ubi]
[  133.416405]  ? seq_read_iter+0x346/0x8a0
[  133.416798]  ? __alloc_pages_slowpath.constprop.0+0x1e30/0x1e30
[  133.417395]  ? __mod_memcg_lruvec_state+0xfe/0x1d0
[  133.417880]  ? seq_read+0x237/0x2f0
[  133.418254]  ? seq_read_iter+0x8a0/0x8a0
[  133.418648]  ? folio_add_lru+0x15d/0x260
[  133.419071]  ? lru_cache_add+0x58/0xf0
[  133.419482]  ? __handle_mm_fault+0x179e/0x2170
[  133.419970]  ? full_proxy_read+0xa3/0x100
[  133.420393]  ? vfs_read+0xff/0x320
[  133.420758]  ? ksys_read+0xcd/0x1e0
[  133.421130]  ? vfs_write+0x5a0/0x5a0
[  133.421493]  ? __kasan_check_write+0x20/0x30
[  133.421931]  ? do_user_addr_fault+0x414/0xff0
[  133.422389]  ? __x64_sys_read+0x46/0x60
[  133.422776]  ? do_syscall_64+0x35/0x80
[  133.423163]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  133.423705]  </TASK>
[  133.423934] 
[  133.424120] Allocated by task 1599:
[  133.424488]  kasan_save_stack+0x26/0x60
[  133.424873]  set_alloc_info+0x4b/0x80
[  133.425247]  __kasan_slab_alloc+0x4c/0x90
[  133.425640]  slab_post_alloc_hook+0x7c/0x5b0
[  133.426062]  kmem_cache_alloc+0x20a/0x5b0
[  133.426454]  ubi_wl_init+0x56d/0xc10 [ubi]
[  133.427173]  ubi_attach+0x291/0x970 [ubi]
[  133.427884]  ubi_attach_mtd_dev+0xe5d/0x1d00 [ubi]
[  133.428721]  0xffffffffa00d0439
[  133.429050]  do_one_initcall+0xb7/0x460
[  133.429457]  do_init_module+0x103/0x420
[  133.429841]  load_module+0x3036/0x3280
[  133.430226]  __do_sys_finit_module+0x14b/0x250
[  133.430654]  __x64_sys_finit_module+0x46/0x60
[  133.431087]  do_syscall_64+0x35/0x80
[  133.431443]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  133.431923] 
[  133.432095] Freed by task 1602:
[  133.432410]  kasan_save_stack+0x26/0x60
[  133.432790]  kasan_set_track+0x29/0x40
[  133.433169]  kasan_set_free_info+0x30/0x60
[  133.433570]  __kasan_slab_free+0x184/0x2c0
[  133.433980]  kmem_cache_free+0x171/0x6f0
[  133.434372]  __erase_worker.cold+0x126/0x472 [ubi]
[  133.435157]  erase_worker+0x14f/0x170 [ubi]
[  133.435879]  do_work+0x146/0x1e0 [ubi]
[  133.436626]  ubi_thread+0x245/0x440 [ubi]
[  133.437347]  kthread+0x1e5/0x250
[  133.437676]  ret_from_fork+0x1f/0x30

【附件信息】
diff

diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 31d427ee191a..77f25a4a1f81 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -418,6 +418,8 @@ static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
 {
 }
 
+#include <linux/delay.h>
+extern int global_pnum;
 static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
 {
 	struct ubi_device *ubi = s->private;
@@ -437,8 +439,13 @@ static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
 	spin_lock(&ubi->wl_lock);
 
 	wl = ubi->lookuptbl[*block_number];
-	if (wl)
+	if (wl) {
+		if (global_pnum == *block_number) {
+			pr_err("%s: access %px\n", __func__, wl);
+			mdelay(5000);
+		}
 		erase_count = wl->ec;
+	}
 
 	spin_unlock(&ubi->wl_lock);
 
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 55bae06cf408..cf8b4cb8a976 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -92,6 +92,7 @@
 #include "ubi.h"
 #include "wl.h"
 
+int global_pnum = -1;
 /* Number of physical eraseblocks reserved for wear-leveling purposes */
 #define WL_RESERVED_PEBS 1
 
@@ -1080,6 +1081,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
  * needed. Returns zero in case of success and a negative error code in case of
  * failure.
  */
+#include <linux/delay.h>
 static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
 {
 	struct ubi_wl_entry *e = wl_wrk->e;
@@ -1091,7 +1093,11 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
 	dbg_wl("erase PEB %d EC %d LEB %d:%d",
 	       pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
 
-	err = sync_erase(ubi, e, wl_wrk->torture);
+	if (lnum >= 0) {
+		pr_err("make err\n");
+		err = -EIO;
+	} else
+		err = sync_erase(ubi, e, wl_wrk->torture);
 	if (!err) {
 		spin_lock(&ubi->wl_lock);
 
@@ -1137,7 +1143,12 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
 		return err;
 	}
 
+	pr_err("free %px\n", e);
+	global_pnum = e->pnum;
+	msleep(3000);
 	wl_entry_destroy(ubi, e);
+	global_pnum = -1;
+	pr_err("freed\n");
 	if (err != -EIO)
 		/*
 		 * If this is not %-EIO, we have no idea what to do. Scheduling

test.sh

#!/bin/bash
set -e

TMP=/root/temp
umount $TMP 2>/dev/null || true
mkdir -p $TMP

modprobe -r ubifs 2>/dev/null || true
for i in $(seq 0 1)
do
	ubidetach -p /dev/mtd$i 2>/dev/null || true
done
modprobe -r ubi 2>/dev/null || true
modprobe -r nandsim 2>/dev/null || true

mtd=/dev/mtd0
ubi=/dev/ubi0

ID="0x20,0x33,0x00,0x00" # 16M 16KB PEB, 512 page

modprobe nandsim id_bytes=$ID parts=400

flash_eraseall /dev/mtd0

modprobe ubi mtd="0,512"
ubimkvol -N vol_a -m -n 0 /dev/ubi0
modprobe ubifs
mount -osync -t ubifs /dev/ubi0_0 $TMP
fsstress -d /root/temp -l0 -n10000 -p 4

评论 (1)

chengzhihao 创建了缺陷

Hi czh549642238, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers: @YangYingliang , @成坚 (CHENG Jian) , @jiaoff , @zhengzengkai , @刘勇强 , @wangxiongfeng , @朱科潜 , @WangShaoBo , @lujialin , @wuxu_buque , @Xu Kuohai , @冷嘲啊 , @Lingmingqiang , @yuzenghui , @juntian , @OSSIM , @陈结松 , @whoisxxx , @koulihong , @刘恺 , @hanjun-guo , @woqidaideshi , @Chiqijun , @Kefeng , @ThunderTown , @AlexGuo , @kylin-mayukun , @Zheng Zucheng , @柳歆 , @Jackie Liu , @zhujianwei001 , @郑振鹏 , @SuperSix173 , @colyli , @Zhang Yi , @htforge , @Qiuuuuu , @Yuehaibing , @xiehaocheng , @guzitao , @CTC-Xibo.Wang , @zhanghongchen , @chen wei , @Jason Zeng , @苟浩 , @DuanqiangWen , @georgeguo , @毛泓博 , @AllenShi , @zhangjialin , @Xie XiuQi

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(2)
5329419 openeuler ci bot 1632792936
C
1
https://gitee.com/openeuler/kernel.git
git@gitee.com:openeuler/kernel.git
openeuler
kernel
kernel

搜索帮助