kasan排查kernel内存越界示例(linux5.18.11)

news2024/10/26 4:26:30

参考资料:

1,内核源码目录中的Documentation\dev-tools\kasan.rst

2,KASAN - Kernel Address Sanitizer | Naveen Naidu (naveenaidu.dev)

一、kasan实现原理

KASAN(Kernel Address SANitizer)是一个动态内存非法访问检测工具. 可以检测 use-after-free 和out-of-bounds两类错误。

KASAN将内存按8字节分一组,每组用一个额外的字节(shadow mem)来记录可访问的字节数。

shadow mem的值:
1)0,8 bytes内存都是可以访问的。
2)N (1 <= N <= 7) ,8 bytes内存的前N个字节可以访问。
3)为负数,8 bytes内存都不可访问,原因见mm/kasan/kasan.h。

mm/kasan/kasan.h

#define KASAN_FREE_PAGE         0xFF  /* page was freed */
#define KASAN_PAGE_REDZONE      0xFE  /* redzone for kmalloc_large allocations */
#define KASAN_KMALLOC_REDZONE   0xFC  /* redzone inside slub object */
#define KASAN_KMALLOC_FREE      0xFB  /* object was freed (kmem_cache_free/kfree) */
#define KASAN_VMALLOC_INVALID   0xF8  /* unallocated space in vmapped page */

二、内存越界示例

代码片段:

1197 static long do_sys_openat2(int dfd, const char __user *filename,
1198                            struct open_how *how)
1199 {
1200         struct open_flags op;
1201         int fd = build_open_flags(how, &op);
1202         struct filename *tmp;
1203         int *kasan;
1204         int i;
1205 
1206         if (fd)
1207                 return fd;
1208 
1209         tmp = getname(filename);
1210         if (IS_ERR(tmp))
1211                 return PTR_ERR(tmp);
1212 
1213         if (!strcmp(tmp->name, "a")) {
1214                 kasan = kmalloc(100, GFP_KERNEL);
1215                 if (kasan) {
1216                         for (i=0; i < 200; i++)
1217                                 *kasan++ = 'a';
1218                         printk("%s %d: kasan test finish\n", __func__, __LINE__);
1219                 }
1220         }
1221 

代码触发的异常log:

cat进程(pid=158),往地址ffff888000949d64写4个字节时,发生内存越界。
[  103.282480] BUG: KASAN: slab-out-of-bounds in do_sys_openat2+0x453/0x4d0
[  103.283613] Write of size 4 at addr ffff888000949d64 by task cat/158
[  103.284310] 
[  103.284928] CPU: 0 PID: 158 Comm: cat Not tainted 5.18.11-gac599649f534-dirty #125
[  103.285796] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014

调用栈:
[  103.287065] Call Trace:
[  103.287479]  <TASK>
[  103.287827]  dump_stack_lvl+0x34/0x44
[  103.288366]  print_report.cold+0xb2/0x6b7
[  103.288995]  ? do_sys_openat2+0x453/0x4d0
[  103.289480]  kasan_report+0xa9/0x120
[  103.289889]  ? do_sys_openat2+0x453/0x4d0
[  103.290218]  do_sys_openat2+0x453/0x4d0
[  103.290554]  ? file_open_root+0x210/0x210
[  103.290978]  do_sys_open+0x85/0xe0
[  103.291329]  ? filp_open+0x50/0x50
[  103.291658]  ? fpregs_assert_state_consistent+0x50/0x60
[  103.292056]  ? __x64_sys_open+0x2a/0x50
[  103.292369]  do_syscall_64+0x3b/0x90
[  103.292691]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  103.293300] RIP: 0033:0x7fbd3899d0bc
[  103.294022] Code: 10 00 00 00 8b 54 24 50 48 89 44 24 30 48 8d 44 24 40 48 89 44 24 38 83 3d 80 a9 07 00 00 48 63 f6 75 21 b8 02 00 00 00 3
[  103.295888] RSP: 002b:00007fff7173b970 EFLAGS: 00000246 ORIG_RAX: 0000000000000002
[  103.297227] RAX: ffffffffffffffda RBX: 00007fff7173bc70 RCX: 00007fbd3899d0bc
[  103.298154] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00007fff7173cf54
[  103.298949] RBP: 00007fff7173cf54 R08: 00007fff7173cfe0 R09: 0000000000000000
[  103.299716] R10: 00007fbd38a192b0 R11: 0000000000000246 R12: 0000000000000000
[  103.300461] R13: 0000000000000000 R14: 0000000000000000 R15: 00007fff7173bc70
[  103.301269]  </TASK>
[  103.301672] 

pid=158的进程分配被越界的内存
[  103.301975] Allocated by task 158:
[  103.302520]  kasan_save_stack+0x1e/0x40

do_sys_open --> kmalloc分配了这块内存
[  103.303045]  __kasan_kmalloc+0x81/0xa0
[  103.303475]  do_sys_openat2+0x434/0x4d0
[  103.303895]  do_sys_open+0x85/0xe0
[  103.304215]  do_syscall_64+0x3b/0x90
[  103.304596]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  103.305212] 
[  103.305516] Last potentially related work creation:
[  103.306069]  kasan_save_stack+0x1e/0x40
[  103.306580]  __kasan_record_aux_stack+0x97/0xa0
[  103.307259]  call_rcu+0x41/0x4c0
[  103.307773]  __inet_insert_ifa+0x3e0/0x4b0
[  103.308288]  devinet_ioctl+0x767/0xb20
[  103.308742]  inet_ioctl+0x24e/0x280
[  103.309210]  sock_do_ioctl+0xb4/0x190
[  103.309719]  sock_ioctl+0x2b1/0x3e0
[  103.310210]  __x64_sys_ioctl+0xb4/0xf0
[  103.310670]  do_syscall_64+0x3b/0x90
[  103.311088]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  103.311696] 

越界的内存块区间为 [ffff888000949d00, ffff888000949d80),该内存块含128个字节(0x49d80 - 0x49d00 = 128)。kmalloc申请100个字节,从kmalloc-128 cache中分配。

[  103.311961] The buggy address belongs to the object at ffff888000949d00
[  103.311961]  which belongs to the cache kmalloc-128 of size 128

从1开始计数,ffff888000949d64在这个区间的第100个byte地址处(0x49d64 - 0x49d00 = 100)
[  103.313130] The buggy address is located 100 bytes inside of
[  103.313130]  128-byte region [ffff888000949d00, ffff888000949d80)
[  103.314341] 

[  103.314742] The buggy address belongs to the physical page:
[  103.315549] page:00000000975ebcd3 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x949
[  103.317102] flags: 0x200(slab|node=0|zone=0)
[  103.318836] raw: 0000000000000200 ffffea0000022240 dead000000000004 ffff8880048418c0
[  103.319675] raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000
[  103.320536] page dumped because: kasan: bad access detected
[  103.321099] 
[  103.321319] Memory state around the buggy address:
[  103.322273]  ffff888000949c00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  103.323105]  ffff888000949c80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc

kasan将内存按8 bytes分为一组,额外用1 byte内存(称作shadow memory)记录每组内存的可访问字节数,下面log中看到的每个字节就是shadow memory的值。第1个位置是00,表示第1组中8字节都可以访问;第13个位置是04,表示13组中前4个字节可以访问。

第100个byte属于第13组的第4个(100 / 8 = 12...4),log中^指向的04表示改组中前4个字节可以访问。

而我们代码1216行,通过for循环会访问到第5个字节,所以触发异常。
[  103.323937] >ffff888000949d00: 00 00 00 00 00 00 00 00 00 00 00 00 04 fc fc fc
[  103.324687]                                                                                               ^
[  103.325414]  ffff888000949d80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  103.326049]  ffff888000949e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc
[  103.326727]

==================================================================
[  103.328184] Disabling lock debugging due to kernel taint
[  103.329028] do_sys_openat2 1218: kasan test finish

三、解析出异常对应的代码行号

如果编译的内核带有debug信息,CONFIG_DEBUG_KERNEL=y 或者选中Kernel hacking --->Kernel debugging,则可用kernel自带的decode_stacktrace.sh脚本解析出行号信息。

命令格式:
decode_stacktrace.sh  vmlinux路径  kernel源码路径  <  crash文件路径  > output.log

root@linux:/home/gsf/debug/kernel/linux-5.18.11# ./scripts/decode_stacktrace.sh /home/gsf/debug/kernel/linux-5.18.11/vmlinux < /home/gsf/kernel.crash

……
[  103.281530] 
[  103.282480] BUG: KASAN: slab-out-of-bounds in do_sys_openat2 (fs/open.c:1217 (discriminator 3))
[  103.283613] Write of size 4 at addr ffff888000949d64 by task cat/158
[  103.284310]
[  103.284928] CPU: 0 PID: 158 Comm: cat Not tainted 5.18.11-gac599649f534-dirty #125
[  103.285796] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  103.287065] Call Trace:
[  103.287479]  <TASK>
[  103.287827] dump_stack_lvl (lib/dump_stack.c:107)
[  103.288366] print_report.cold (mm/kasan/report.c:314 mm/kasan/report.c:429)
[  103.288995] ? do_sys_openat2 (fs/open.c:1217 (discriminator 3))
[  103.289480] kasan_report (mm/kasan/report.c:162 mm/kasan/report.c:493)
[  103.289889] ? do_sys_openat2 (fs/open.c:1217 (discriminator 3))
[  103.290218] do_sys_openat2 (fs/open.c:1217 (discriminator 3))
[  103.290554] ? file_open_root (fs/open.c:1199)
[  103.290978] do_sys_open (fs/open.c:1238)
[  103.291329] ? filp_open (fs/open.c:1238)
[  103.291658] ? fpregs_assert_state_consistent (arch/x86/kernel/fpu/context.h:39 arch/x86/kernel/fpu/core.c:772)
[  103.292056] ? __x64_sys_open (fs/open.c:1248 fs/open.c:1244 fs/open.c:1244)
[  103.292369] do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)

……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1497311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcoder Day39| 动态规划part06 完全背包问题

完全背包理论 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 示例&#xff1a; 背包最大…

CentOS下安装RabbitMQ

准备工作&#xff0c;更新yum源 正式环境慎用 yum update -y # 进入目录 cd /etc/yum.repos.d/ # 创建目录 mkdir backup # 默认源配备份 mv C* backup/ # 下载阿里云yum源 wget -O /etc/yum.repos.d/CenOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # 清除旧…

【BUG修复日志】Anaconda + VSCode 编码错误

【BUG修复日志】Anaconda VSCode 编码错误 平台: Windows11家庭版 (v22621.3155) 软件: Visual Studio Code (v1.87.0) 插件: Python (v2024.2.1) 版本: Conda (v24.1.2)问题描述 VSCode 在安装 Python 插件的情况下自动提示配置 Conda 环境&#xff0c;但是在自动配置完成后…

P9889 [ICPC2018 Qingdao R] Plants vs. Zombies 题解 二分+贪心

[ICPC2018 Qingdao R] Plants vs. Zombies 传送门 题面翻译 给定 n n n 个植物和 m m m 的步数限制&#xff0c;每个植物在位置 1 … n 1\dots n 1…n 上。你初始时在位置 0 0 0&#xff0c;每次可以移动到相邻的位置上。 每次设你走完一步后到达的位置是 i i i&#…

LeetCode每日一题之 快乐数

目录 题目介绍&#xff1a; 算法原理&#xff1a; 鸽巢原理&#xff1a; 如何找到环里元素&#xff1a; 代码实现&#xff1a; 题目介绍&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a; 我先简单举两个例子&#xff…

最新的前端开发技术(2024年)

关于作者&#xff1a; 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0…

如何将虚拟机设置成固定IP

问题描述&#xff1a; 在VMware虚拟机上部署的项目ip地址和数据库ip地址发生变动&#xff0c;导致mysql,nginx,redis等无法访问&#xff0c;要改配置又特别麻烦&#xff0c;而且下次可能还会变动。 解决方法&#xff1a; 将虚拟机ip地址配置成固定ip 关闭虚拟机&#xff0c;找…

ai数字人虚拟直播:AI大模型带给你不一样的体验

AI数字人虚拟直播&#xff0c;这一新兴的科技形式&#xff0c;正逐渐融入人们的生活之中。通过AI大模型的技术支持&#xff0c;数字人可以实现高度仿真的互动体验&#xff0c;让观众感受到前所未有的沉浸式乐趣。 数字人虚拟直播的魅力在于其超越了传统直播形式的局限性&#…

R语言lavaan结构方程模型在复杂网络分析中的科研技术新趋势

此外&#xff0c;我们还将深入探讨R语言的基础知识、结构方程模型的基本原理、lavaan程序包的使用方法等内容。无论是潜变量分析、复合变量分析&#xff0c;还是非线性/非正态/缺失数据处理、分类变量分析、分组数据处理等复杂问题&#xff0c;我们都将一一为您解析。 希望通过…

谷粒商城实战(002 oss 文件储存系统)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第61p-第p101的内容 简介 P61 服务器 对象存储服务 OSS 也可以用minio 三种上传方式 推荐第三种 1.过服务器 安全 但是占用性能 2.不过服…

Kubernetes-3

Kubernetes学习第3天 Kubernetes-31、查看实时的cpu和内存消耗1.1、kubectl top node 2、卷的使用2.1、什么是卷&#xff1f;1. 解决数据持久性问题2. Kubernetes 中的卷抽象概念3. 共享数据示例4. Kubernetes 中的卷使用5. 不同类型的卷6. 灵活、可靠的数据管理 2.2、联想到do…

前端每日一练 :相邻元素、嵌套元素Margin 塌陷、合并问题如何额解决?

相邻元素外边距塌陷合并 表现示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</t…

旧物回收小程序开发:环保与科技的创新结合

随着科技的飞速发展&#xff0c;我们的日常生活越来越离不开手机应用程序。而在环保日益成为社会焦点的今天&#xff0c;如何将科技与环保相结合&#xff0c;成为了一个值得深思的问题。今天&#xff0c;我们将探讨旧物回收小程序的开发&#xff0c;它如何助力环保&#xff0c;…

nginx代理访问Kuboard, 解决日志无法查看问题

错误方式 这种代理方式在点击追踪日志按钮, 会无法查看日志, 因为日志是通过weboscket传输 worker_processes 1; #设置 Nginx 启动的工作进程数为 1。events {worker_connections 1024; ##设置每个工作进程的最大并发连接数为 1024。 }http {include mime.types; #该…

社区店选址案例研究:成功与失败的经验教训

大家好&#xff0c;我是一名鲜奶吧5年的创业者&#xff0c;在社区店经营方面有着丰富的经验。 今天&#xff0c;我将分享一些关于社区店选址的成功与失败案例&#xff0c;希望能给想开实体店或创业的朋友们提供有价值的干货信息。 首先&#xff0c;让我们来看看成功的社区店选…

【Leetcode每日一题】 前缀和 - 除自身以外数组的乘积(难度⭐⭐)(27)

1. 题目解析 题目链接&#xff1a;238. 除自身以外数组的乘积 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给数组除本身外其他元素的积的数组返回即可。 2. 算法原理 为了计算每个位置i的最终结果ret[i]&…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础组件:AlphabetIndexer)

可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 AlphabetIndexer(value: {arrayValue: Array<string>, s…

python_读取txt文件绘制多条曲线

读取txt文件&#xff0c;将匹配条件的多列绘制成曲线展示&#xff1a; import matplotlib.pyplot as plt import re from datetime import datetime from pylab import mplmpl.rcParams["font.sans-serif"] ["SimHei"] # 设置显示中文字体 mpl.rcParam…

uniapp+node.js前后端做帖子模块:发布帖子评论(社区管理平台的小程序)

目录 0前提1.一些准备1.1表帖子表 post帖子评论表 postComment 1.2总体思路 2.前端3.后端4.验证结果 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你的青睐是我努力的方向&#xff01; ✏️ 评论&#xff0c;你的意见是我进步的…

还为没有本科学历发愁?2024年成人学历提升最全攻略

如果你因为学历低而处处不顺的时候&#xff0c; 请记着&#xff0c; 我们还有提升学历的机会&#xff01; 成人想提升学历有三大方式&#xff1a;成人高考&#xff0c;自学考试&#xff0c;开放大学。 通过这几种途径获得的文凭都是国家承认&#xff0c;学信网可查的&#x…