司的就是国际这条线;马上追踪热点
秘闻背后的事;我给你说透
欢迎各位看官收看今天的【司马秘事】
文:司马秘事
编辑:司马秘事
12月16日,Linux内核维护者GregKroah-Hartman发了封邮件,直接炸了技术圈。
主线Linux内核里一段Rust代码,被正式登记为CVE漏洞,编号CVE-2025-68260。
这可是Linux内核Rust代码头一回拿到CVE编号,之前一直吹Rust内存安全的朋友们,怕是得重新琢磨琢磨了。
漏洞藏在哪?unsafe代码出了岔子
这次出问题的地方不复杂,就在用Rust重写的AndroidBinder驱动里,这驱动还有个专属名字叫rust_binder。
它的作用挺关键,负责Android系统里不同进程之间的通信,相当于进程间的“传话筒”。
问题就出在一段带unsafe标记的代码上,开发团队本来觉得,这段代码操作的节点只会属于一个链表,只要拿了锁就不会有并发问题。
可现实狠狠打了脸,他们没考虑到,这个节点可能还存在于另一个会被同时访问的链表中。
修改链表的prev和next指针时,必须保证没有其他线程插手。
一旦有其他线程也在改这两个指针,内存结构直接就乱了套。
本来想这只是个小疏忽,但后来发现,正是这个疏忽让安全防线出现了缺口。
咋触发的?两步操作+并发冲突
搞清楚漏洞所在,咱再说说它是怎么被触发的,这个漏洞的触发流程,其实一点都不绕。
Node::release方法执行时,第一步是拿锁,锁拿到手后,会把原链表的所有元素都移到栈上的本地链表。
接着锁就被释放了,然后再遍历本地链表处理元素,麻烦就出在“释放锁”和“处理元素”之间。
如果这时候有其他线程,正好对原来的链表执行那个unsafe的remove操作,两个线程同时改同一个节点的指针。
如此看来,链表不被搞乱才怪,最终直接导致内核崩溃。
有网友贴出了实际崩溃的日志,虚拟地址触发了分页错误,调用栈明明白白指向rust_binder模块。
这种崩溃不是小毛病,会让整个系统直接“罢工”,好在暂时没发现能远程利用的风险。
影响多大?社区吵翻了天
这次漏洞波及的范围不算广,只影响Linux6.18及之后的版本。
毕竟rust_binder驱动是6.18版本才引入内核的,老版本根本没有这段代码,自然也就不受影响。
危害程度也相对可控,最多就是让系统崩溃,不会出现数据泄露或者远程代码执行这种更严重的情况。
Greg在公告里也说了,当天还有159个内核CVE是针对C语言代码的,对比下来,Rust的表现其实不算差。
但社区的争论可没停,有网友觉得,要是Rust非得用unsafe才能解决问题,那这责任就得算在Rust身上。
也有人反驳,觉得指望把代码改成Rust就没bug,本身就是天真想法。
我倒觉得,双方说得都有道理,Rust从来没说过自己能根治所有bug,它只是帮开发者避开大部分内存安全坑。
咋修复?简单粗暴但有效
面对这个漏洞,修复思路其实很直接,开发团队放弃了“先移到本地链表再处理”的做法。
改成直接在原链表上逐个弹出节点处理,这样一来,处理节点的时候,链表还处于锁定状态,其他线程根本没机会插手修改。
这个改动不算复杂,但正好命中了问题的核心。
目前6.18.1和6.19-rc1版本已经完成了修复,升级到这些版本就能规避风险。
这次事件给所有用Rust做底层开发的人提了个醒。
unsafe不是洪水猛兽,它是Rust兼顾性能和底层操作能力的必要设计,但用的时候必须慎之又慎。
开发者不能指望语言本身帮自己挡住所有风险,规范的开发流程和充分的测试同样重要。
毫无疑问,Rust依然是目前最安全的系统级编程语言之一。
这次的CVE不是Rust的“翻车”,而是一次正常的技术迭代插曲。
随着Rust在内核中的应用越来越广,类似的小漏洞可能还会出现,但这并不影响它成为减少内核漏洞的重要力量。
对普通用户来说,及时升级内核版本,就是保障系统安全最实在的办法。
世界从不平静,司马为您解析,今天到此为止,下期我们再见!