本文经授权转自公众号CSDN(ID:CSDNnews)
距离「719 微软蓝屏事件」刚过去一个月,诸多企业还没有从这场“史上最大规模 IT 故障”的影响中彻底走出,如今又有一个核弹级的 Linux 内核重大安全漏洞被曝出:著名系统内核专家、《软件调试》作者张银奎发表了一篇文章,在技术圈内引起了广泛关注——《
是谁在 LINUX 内核中开了这个大洞?
》。
据张银奎表示,若该漏洞被黑客利
用并爆发,其造成的后果将“超过 719 大蓝屏”。
1、一个“诡异的 oops”,引起注意
在介绍漏洞之前,有一点需明确:由于该漏洞尚处于 0day 阶段,相关细节敏感,因此张银奎仅分享了漏洞的可公开信息,并未公开敏感的技术细节部分。
根据张银奎在文中提到的内容,这个漏洞最初能被注意到,是因为他们的内核开发团队在测试专门为程序员打造的移动计算平台“幽兰”的系统镜像时,将内核升级到 6 + Ubuntu 24.04 之后,出现了一个随机的内核 oops(指 Linux 内核发生不正确的行为并生成错误报告),这个 “oops” 一旦发生,就会导致声音无法播放、reboot 失败等一系列问题——张银奎将其形容为:“一个诡异的 oops”。
本质上来说,这个 oops 与造成 719 蓝屏事件的原因类似,也是非法访问内存,即越界。但它的奇怪之处在于,这个越界访问的内存地址很长:003a72656c646e69。
图源:格友公众号
凭借多年经验,张银奎很快看出这个长地址中包含了很多可读的 ASCII 字符。稍作解释一下,内存地址的数据是由程序执行的代码或存储的数据决定的,它们往往是二进制格式,不容易直接读取为有意义的文本字符串。倘若出现了这种情况,可能会暴露程序的漏洞。攻击者可以利用这些漏洞进行恶意攻击,如通过缓冲区溢出注入恶意代码、执行任意代码、或窃取敏感数据。
为了搞清楚其中到底发生了什么,张银奎用 windbg 的 .formats 命令转换后,得到了以下结果:错误地址刚好对应的是「 :reldni」这 8 个字符。将这 8 个字符的顺序调整后,就是"indler: "(注意冒号后面还有一个空格)——为了方便描述,暂且把该漏洞称为 indler 漏洞。
0:000> .formats 203a72656c646e69
Evaluate expression:
Hex: 203a7265`6c646e69
Decimal: 2322294337798696553
Octal: 0200723446255431067151
Binary: 00100000 00111010 01110010 01100101 01101100 01100100 01101110 01101001
Chars: :reldni
Time: Wed Jan 23 00:02:59.869 8960 (UTC + 8:00)
Float: low 1.10463e+027 high 1.57927e-019
Double: 1.9725e-153
据张银奎介绍,这个 oops 是随机的,而根据 oops 提供的函数地址,发生崩溃的内核函数名叫 sysfs_file_ops,源代码如下:
static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn)
{
struct kobject *kobj = kn->parent->priv;
if (kn->flags & KERNFS_LOCKDEP)
lockdep_assert_held(kn);
return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
}
对此,张银奎笃定:“对于这样的内存溢出问题,这肯定不是第一现场。这只是一个受害者。”
为了找到这个“第一现场”,即造成内存溢出的元凶,
张银奎及其
内部团队试了很多办法都不能有效定位,张银奎决定采用最直接的方式:用集成在 Linux 内核中的内存错误检测工具 KASAN(Kernel Address Sanitizer),这款工具由 Google 工程师开发。
团队成员把启用了 KASAN 的内核成功运行后,很快就找到了一个内存越界写(又称为缓冲区溢出)。张银奎仔细查看了内核消息:
[ 25.146063] kasan: KernelAddressSanitizer initialized (generic)
[ 33.918201] ==================================================================
[ 33.918234] BUG: KASAN: slab-out-of-bounds in __memcpy_fromio+0x8c/0x100
[ 33.918259] Write of size 8 at addr ffffff8101838afc by task systemd/1
[ 33.918283] CPU: 5 PID: 1 Comm: systemd Not tainted 6.1.43-rockchip-rk3588-taiyi #1.0.8
[ 33.918300] Hardware name: YourLand CodeBook (DT)
[ 33.918312] Call trace:
[ 33.918324] dump_backtrace+0xd0/0x130
[ 33.918338] show_stack+0x20/0x30
[ 33.918350] dump_stack_lvl+0xac/0xe0
[ 33.918368] print_report+0x164/0x464
[ 33.918384] kasan_report+0xc8/0x1a0
[ 33.918400] __asan_store8+0x80/0xa4
由于涉及到敏感的安全问题,张银奎省略了代码中很多的调用栈。在关于这次非法方法的详细细节中,他也省略了一些具体函数名:
[ 33.919049] The buggy address belongs to the object at ffffff8101838000
which belongs to the cache kmalloc-4k of size 4096