包阅导读总结
1. 内核崩溃、AnolisOS 8.8、静态分析、debug、crash原因
2. 本文讲述在 AnolisOS 8.8 操作系统上,对内核崩溃问题进行静态分析 debug 的过程,最终找出原因并解决。
3.
– 问题背景
– 用户机器安装 AnolisOS 8.8 系统镜像过程中内核崩溃,无 coredump,只有屏幕打印信息。
– 调试过程
– 确定内核版本为 5.10.134-13。
– 分析汇编代码,确认问题出在 resctrl_mon_resource_init 函数中的循环结构结束处。
– 找到 dom_data_init 函数中 kcalloc 返回不合法值导致后续访问内存时 panic。
– 发现是客户机器 cpu 不支持 CQM_LLC 导致。
– 问题解决
– 出验证内核,用户验证问题解决。指出完整解决涉及 resctrl 整体 init 逻辑,是历史遗留问题。
思维导图:
文章地址:https://mp.weixin.qq.com/s/cAqTC_3gKd6nuy__-kdAyw
文章来源:mp.weixin.qq.com
作者:库恩
发布时间:2024/8/7 9:28
语言:中文
总字数:2386字
预计阅读时间:10分钟
评分:84分
标签:内核调试,静态分析,AnolisOS,内核崩溃,汇编分析
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
一般的debug的手段无非是依赖gdb、coredump,那是因为gdb类似的动态调试工具非常完善,可以帮助我们极快地完成debug。除此之外,debug还有一种方式,就是纯静态分析,在条件有限的情况下,gdb类的动态工具无法施展拳脚,只能依靠人脑模拟cpu运行以静态的方式来debug了。
有用户在OpenAnolis Kernel SIG群里发了个有点模糊的截图和一句话:
经过简单询问发现客户机器是12代intel i5-12400,在安装官网上下载的AnolisOS 8.8系统镜像过程中crash,无法进入系统,没有coredump,只有这个屏幕的打印的信息,无法看到更多的log。
好了,这就是所有的信息,现在开始debug阶段。
从log中可以看到当cpu执行到resctrl_mon_resource_init+0xc0的地方时出现了panic,因此需要找到:
resctrl_mon_resource_init+0xc0
-
这里需要将对应的vmlinux解析成汇编,通过objdump -S -I -z vmlinux > vmlinux.txt解析成汇编的形式,解析出来最左边是地址,中间是二进制,右边是二进制对应的汇编代码。
-
通过解析出来的汇编可以看到resctrl_mon_resource_init函数的地址是ffffffff8148eea0,0xc0是ffffffff8148ef60,对应截图中的RIP 部分的二进制,刚好都能对应上,因此可以确认就是这里出现了问题。
-
到底汇编对应代码的哪里呢?这里分享个小经验:在汇编代码里面看到类似这样的结构,一个向下的大跳+一个向上的小跳,这种结构一般对应代码中的循环结构。汇编中的向上跳转比较特殊,一般只有在goto、循环这样的结构才能汇编出向上跳的情况。可以看到crash时RIP指向了一个循环结构结束的地方。
-
在resctrl_mon_resource_init()——
dom_data_init()中发现了这个for循环,大概捋一下汇编代码前后的逻辑基本就能很快确定crash的时候RIP执行到了dom_data_init()第23行的位置。
-
dom_data_init() 23行中:
resctrl_arch_rmid_idx_encode(0,0)返回0,然后在rmid_ptrs中取第0个元素并返回。
-
通过对汇编分析,可以知道在crash RIP处,RBX就是rmid_ptrs。
-
所以原因就很明显了,crash是因为dom_data_init()中kcalloc()返回了一个非空,但是却不合法的值。在后续的代码中又对这个值取地址操作,产生了panic!
所以为啥kcalloc()会返回0x10呢?我们可以看到nr_idx是从下方函数来的:
resctrl_arch_system_num_rmid_idx()
而resctrl_arch_system_num_rmid_idx()的返回值为:
x86_cache_max_rmid + 1
通过内容安全API提供直播场景的文本检测能力,响应时间短、支持类型多,多维度判断风险行为。
点击阅读原文查看详情。