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)

……

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#与python交互(flask发送Get/Post请求)

先运行python&#xff0c;再运行C# **ps: 注意修改端口号**python发送Get/Post请求 # -*- coding: utf-8 -*- # Time : 2024/1/25 15:52 # Author : YY # File : post_test.py # Content&#xff1a;提交数据给客户端 from flask import Flask, request, jsonify, redirect…

使用Kali搭建钓鱼网站教程

一、前言 使用kali工具一分钟制作出和目标网站一模一样的钓鱼网站。目标用户使用钓鱼网站登录自己的账号&#xff0c;账号密码将被自动劫持。 二、钓鱼网站的制作过程 1.在虚拟机VMvare中登录kali linux 2.准备一个目标网址 3.在kail中搜索使用工具 4.在弹出的选项中选择第一…

C++初阶:初识C++

目录 1. 前言&#xff1a;C 与 C语言2. C对于C语言语法的完善与补充2.1 命名冲突与命名空间2.1.1 命名空间的定义2.1.2 调用方式 2.3 补充&#xff1a;流的概念2.4 缺省参数2.4.1 缺省参数的使用 2.5 函数重载2.5.1 什么是函数重载2.5.2 函数重载的使用2.5.3 特殊情况&#xff…

Docker基础教程 - 1 Docker简介

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 1 Docker简介 Docker是一个强大的容器化平台&#xff0c;让你能够更轻松地构建、部署和运行应用程序。 下面我们来学习 Docker。 1.1 Docker是什么 1 现在遇到的问题 每次部署一台服务器&…

OpenAI 大声朗读出来

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

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…

[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

在 SpringBoot3 中使用 Mybatis-Plus 报错

在 SpringBoot3 中使用 Mybatis-Plus 报错 Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required Caused by: java.lang.IllegalArgumentException: Property sqlSessionFactory or sqlSessionTemplate are requiredat org.springframework.util.Assert.no…

Android随手记

activity的生命周期 创建时 onCreate() - onStart() - onResume() - onPause() - onStop() - onDestroy() 切换时 a切换到b a.onCreate() - a.onStart() - a.onResume - a.onPause - b.onCreate() - b.onStart() - b.onResume() - a.onStop() b切换回a b.onPause() - a.onR…

C++ 路径问题

目录 例1 例2 例3 例4 例5 例6 例1 62. 不同路径 1.初始化 2.当前位置的条数&#xff0c;就是上面位置的条数 &#xff0c;加上其左边位置的条数&#xff0c;dp[i][j] dp[i - 1][j] dp[i][j - 1]; 参考代码 class Solution { public:int uniquePaths(int m, int n) …

蓝桥杯——123

123 二分等差数列求和前缀和数组 题目分析 连续一段的和我们想到了前缀和&#xff0c;但是这里的l和r的范围为1e12&#xff0c;明显不能用O(n)的时间复杂度去求前缀和。那么我们开始观察序列的特点&#xff0c;可以按照等差数列对序列进行分块。如上图&#xff0c;在求前10个…

Python爬虫实战(基础篇)—13获取《人民网》【最新】【国内】【国际】写入Word(附完整代码)

文章目录 专栏导读背景测试代码分析请求网址请求参数代码测试数据分析利用lxml+xpath进一步分析将获取链接再获取文章内容测试代码写入word完整代码总结专栏导读 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门针对于有爬虫基础准备的一套基础教学,轻松掌握Py…

idea Gradle 控制台中文乱码

如下图所示&#xff0c;idea 中的 Gradle 控制台中文乱码&#xff1a; 解决方法&#xff0c;如下图所示&#xff1a; 注意&#xff1a;如果你的 idea 使用 crack 等方式破解了&#xff0c;那么你可能需要在文件 crack-2023\jetbra\vmoptions\idea.vmoptions 中进行配置&#xf…

Qt for WebAssembly : Application exit (SharedArrayBuffer is not defined)

用Qt开发 WebAssembly&#xff0c;放到nginx里面&#xff0c;用127.0.0.1访问没问题&#xff0c;用局域网IP访问就提示如下&#xff1a; 总结了以下两种解决办法&#xff1a; ①&#xff1a;配置 nginx http 头 [ 支持&#xff1a;WebAssembly Qt (single-threaded) ] ②&#…

生成商品条码

php生成商品条码&#xff0c;编码格式为&#xff1a;EAN13 下载第三方包&#xff1a;composer require codeitnowin/barcode 生成条码代码&#xff1a; $filename \Str::random(40) . .png;$barcode new BarcodeGenerator();$barcode->setText($barCode);$barcode->s…

Vue3.0 vue.js.devtools无法显示Pinia调试工具

之前的配置方式&#xff1a; app.use(createPinia()) app.mount(#app) 更新配置方式&#xff1a; app.use(createPinia()).mount("#app") 设置之后即可显示调试工具

吴恩达deeplearning.ai:数据增强数据合成迁移学习

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 让我们看看为你的程序添加数据的技巧。在构建神经网络的时候&#xff0c;我们总是想要更多的数据&#xff0c;但是获取更多的数据往往是十分昂贵又缓慢的。相反地&#xff0c;添加数据的另一…

Android耗电分析之Battery Historian工具使用

Battery-Historian是谷歌推出的一款专门分析Bugreport的工具&#xff0c;是谷歌在2015年I/O大会上推出的一款检测运行在android5.0(Lollipop)及以后版本的设备上电池的相关信息和事件的工具&#xff0c;是一款对于分析手机状态&#xff0c;历史运行情况很好的可视化分析工具。 …

Flink实时数仓之用户埋点系统(一)

需求分析及框架选型 需求分析数据采集用户行为采集业务数据采集 行为日志分析用户行为日志页面日志启动日志APP在线日志 业务数据分析用户Insert数据用户Update数据 技术选型Nginx配置Flume配置MaxWellHadoopFlink架构图 需求分析 数据采集 用户行为采集 行为数据&#xff1…

IR 召回测试数据集——MS MARCO

如何评估召回系统的好坏&#xff1f;如何评估检索系统是否有提升&#xff1f;在任何人面前&#xff0c;空口无凭。 我们需要一把尺子来衡量。我们需要一个高质量的测试数据集合。每次都在相同的测试数据集上&#xff0c;进行评测。本篇文章介绍一个高质量的应为的测试数据集——…