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

参考资料:

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)

……

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《JAVA与模式》之模板方法模式

系列文章目录 文章目录 系列文章目录前言一、模板方法模式的结构二、模板方法模式中的方法三、使用场景四、模板方法模式在Servlet中的应用前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了…

RN开发搬砖经验之-如何处理FlashList组件加载后调用scrollToIndex没有滚动指定位置

前言 如题&#xff0c;这里只能说是处理&#xff0c;起正向作用的临时方案&#xff0c;因为我也着实没搞懂这个BUG的具体原因&#xff0c;看github上有提相关的issuesFor long lists with different item types scrollToIndex does not work reliable&#xff0c;但看官方没有…

操盘风控系统的功能设计与实现

文章目录 一、账户信息风控警报系统是什么二、操盘警报风控系统的意义三、风控系统功能参数设置短信通知及邮件通知参数手机远程风控新闻风险控制常规Bug检测、交易纪律控制参数账户净值、手数、单数、盈亏控制参数价格时间风控、定时平仓 一、账户信息风控警报系统是什么 警报…

WPF学习三(MVVM+自定义按钮等的登录界面)

跟着bilibil龙马哥视频做的一个登录界面&#xff0c;个人感觉讲得很到位&#xff0c;适合新手&#xff09;&#xff0c;他是从开始的前后绑定慢慢解耦合到MVVM&#xff0c;让我较快的理解了WPF的基础。 【WPF入门】WPF零基础到精通&#xff0c;从概念到实操&#xff0c;步步提升…

「AI工程师」模型训练与部署-工作指导

工作指导书 一、工作职责 负责AI模型的训练和优化&#xff0c;确保模型性能达到预定目标。协调资源的分配&#xff0c;管理训练过程中的各种参数和配置。负责模型的部署工作&#xff0c;确保模型能够稳定、高效地运行在实际环境中。监控模型的运行状态&#xff0c;及时处理和…

Python实现滚动加权最小二乘法回归模型(RollingWLS算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 滚动加权最小二乘法回归模型&#xff08;Rolling Weighted Least Squares, RollingWLS&#xff09;是一…

基于SSM的房客源信息管理系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术 3 1.1 SSM框架 3 1.2 Vue框架 3 1.3 ECharts 3 1.4 JQuery技术 3 1.5 本章小结 4 2系统分析 5 2.1 需求分析 5 2.2 非功能需求 8 2.3 本章小节 8 3 系统设计 9 3.1 系统总体设计 9 3.1.1 系统体系结构 9 3.1.2 系统目录结构 9 3…

MySQL 针对逗号拼接的数据字段转行思路

一、MySQL 针对逗号拼接的数据字段转行思路 在 MySQL 中我们有可能为了方便操作&#xff0c;有时会将一个字段存储多个信息&#xff0c;使用英文逗号隔开&#xff0c;当然这种情况属于对数据库的设计上有些欠妥。但如果遇到了这种情况又需要对数据进行统计的情况就有点棘手了&…

直流负载原理与应用

直流负载是指能够消耗直流电能的设备或系统&#xff0c;在电力系统中&#xff0c;直流负载主要包括直流电动机、蓄电池、电解槽等。这些设备在运行过程中需要消耗大量的直流电能&#xff0c;因此对直流电源的稳定性和可靠性要求较高。本文将对直流负载的原理及其应用进行简要介…

二叉树(属性、修改与构造)

226. 翻转二叉树 题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]答案 class Solution {public TreeNode invertTree(TreeNode roo…

python3安装chrome,chromedriver亲测有效

客户用python写了个脚本&#xff0c;需要用到chrome和chromedriver扩展&#xff0c;结果说安装不了&#xff0c;各种报错&#xff0c;好吧我来研究一下。众所周知linux自带python2.7&#xff0c;根据报错查了一下资料发现是版本冲突导致的&#xff0c;系统自带2.7&#xff0c;代…

针对ETC系统的OBE-SAM模块设计方案

ETC&#xff08;Electrical Toll Collection&#xff09;不停车收费是目前世界上最先进的路桥收费方式。通过安装在车辆挡风玻璃上的车载单元与安装在收费站 ETC 车道上的路侧单元之间的微波专用短程通讯&#xff0c;利用计算机联网技术与银行进行后台结算处理&#xff0c;从而…

typescript 学习

一.typescript是Javascript的超集,在javascript中添加特性的语言扩展,支持ES6标准。 二.typescript中新增了:类型批注和编译时类型检查,类型推断,类型擦除,接口,枚举,Mixin,泛型编程,名字空间,元组,await等 三.vscode 中怎样使用typescript 1. 安装VSCode (官网下…

SSL 证书,了解一下常识

公司的网站、应用怎么才能保证在互联网上安全运行&#xff0c;不被攻击、盗取数据呢&#xff1f; 创业必经之路&#xff0c;一步一步走就对了&#xff0c;可能没赶上红利期&#xff0c;但不做就等于0。 概述 SSL 证书&#xff08;SSL Certificates&#xff09;又称数字证书&am…

常见控件应用

常见控件应用 1.操作Ajax选项2.滑动滑块操作 1.操作Ajax选项 Ajax即Asynchronous JavaScript and XML&#xff08;异步JavaScript和XML&#xff09;&#xff0c;是指一种创建交互式、快速动态网页应用的网页开发技术。通过在后台与服务器进行少量数据交换&#xff0c;Ajax可以…

Python与FPGA——图像锐化

文章目录 前言一、图像锐化二、Python robert锐化三、Python sobel锐化四、Python laplacian锐化五、FPGA sobel锐化总结 前言 在增强图像之前一般会先对图像进行平滑处理以减少或消除噪声&#xff0c;图像的能量主要集中在低频部分&#xff0c;而噪声和图像边缘信息的能量主要…

Spring Boot 生成与解析Jwt

Spring Boot 生成与解析Jwt Maven依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency>生成&解析 package yang;import io.jsonwebtoken.Claims…

DDS技术概述及测试策略与方案

随着车载通信技术的快速发展&#xff0c;传统的通信技术在满足车载通信需求方面面临着一些挑战。车载通信对实时性、可靠性以及通信带宽的需求越来越高&#xff0c;同时车载通信环境存在多路径衰落、信号干扰等问题&#xff0c;这些都给通信技术的选择和应用带来了一定的挑战。…

沐风老师3DMAX快速布尔QuickBoolean插件安装和使用教程

3DMAX快速布尔QuickBoolean插件安装和使用教程 3DMAX快速布尔QuickBoolean插件是一组工具&#xff0c;用于对具有预设轮廓的当前选定对象快速执行ProBoolean运算&#xff0c;如并集、相交、空心、修剪、减法、拆分和刀。 它的工作原理与SketchUp的Solid Tools非常相似&#xf…

qt如何配置ros环境

在Qt5.7的版本可以使用bash -i -c来启动qt&#xff0c;让Qt自己识别系统环境&#xff0c;不知道为什么Qt在之后的版本&#xff0c;这样使用都失效了。因为它会默认把CMAKE_PREFIX_PATH修改掉。 网上还有安装ros插件版本的qt creator&#xff0c;感觉失去了一些灵活性。 自己测试…