删掉 1.1 万行 C 代码,Rust 正式接手 Android Binder

Linux 正在用 Rust 替换 Android Binder 驱动的 C 实现。这说明,内存安全正在变成实际的工程选择。

15 年多来,Android 的 Binder 驱动一直在帮助应用和系统服务相互通信。用户可能从未见过这个组件,但很多操作都离不开它。Android 应用向操作系统请求服务时,Binder 会帮助完成进程之间的通信。

在这段历史的大部分时间里,这个驱动都是用 C 编写的。

现在,Rust 来了。

Linux 内核正在移除 Binder 的旧 C 实现,转向 Rust 版本。这项变更已在 Linux 7.4 开发周期中合入,Google 也计划把后续 Binder 开发集中到 Rust 版本上。

这不只是又一个 Rust 驱动进入内核。一个长期使用的实现正在被移除,因为替代版本已经成熟,足以接过它的工作。

Google 工程师 Carlos Llamas 表示,随着复杂度增长,旧实现越来越难维护。Rust 版本经过数年开发,已经实现了功能对齐;据报道,在一些测试中,它的性能已经达到甚至超过 C 实现。

C 过时了吗?没有。但 Rust 正在接手一个重要且广泛使用的系统组件,这说明,Rust 可以上桌了!

Binder 是什么

Android 应用并不是独自运行的,应用可能需要与系统服务通信,以获取信息、使用硬件功能,或执行需要更高权限的操作。

这些进程通常有各自独立的地址空间。一个进程不能直接访问另一个进程的内存,像在同一个程序里那样调用函数。

它们需要一种受控的通信机制。这就是进程间通信,也就是 IPC,要解决的问题。

Binder 是 Android 的核心 IPC 机制之一。Binder 驱动与 Android 用户空间中的库和服务配合,完成进程之间的事务通信。

简化后的流程大致如下:

text 复制代码
Android application
        |
        v
Android framework / IPC interface
        |
        v
Binder driver in the Linux kernel
        |
        v
Target system service

这只是概念示意,并没有完整呈现每一次 Binder 事务的具体过程。

Binder 位于用户空间应用与内核管理的通信机制之间。它需要处理事务、进程状态、线程、引用和内存等复杂操作。

这样的组件一旦出现缺陷,后果可能很严重。过去,Binder 曾多次修复与内存管理和事务处理有关的安全问题,因此,可维护性也是一个重要考量。

所以,替换它绝不只是换种语言重新实现那么简单。新实现必须保留 Android 软件所依赖的行为。

为什么要移除 C 实现

C 能直接控制内存和底层资源,因此一直是操作系统开发中的重要语言。

但这种控制能力也伴随着风险。

使用 C 时,开发者必须小心管理指针、对象生命周期、内存分配和缓冲区边界。出错可能导致内存损坏、释放后使用(use-after-free)漏洞,或程序崩溃。

Binder 的复杂性让这些工作尤其困难。多年来,为了满足 Android 不断增长的需求,这个驱动持续演进。不同功能之间的相互作用,也让开发者更难判断一次修改会产生什么影响。

在 2026 年 9 月提交的移除补丁中,Google 工程师 Carlos Llamas 解释说,C 驱动的维护已经越来越吃力,要在不引入漏洞的前提下添加新功能也很困难。

这不是说所有 C 实现都不安全,也不意味着用 Rust 重写就能自动消除所有安全漏洞。

这次改动,直白点讲,是因为 Rust 在语言层面提供了保护,可以在安全 Rust 代码中防止许多内存安全错误。

这些保护能减少开发者需要手动处理的危险状态。其实你可以简单地理解为:在这些能由编译器检查的规则上,程序员是不值得信任的,编译器才值得。

为了满足底层系统编程的需求,Rust 仍然允许显式使用 unsafe 操作。逻辑错误、错误的权限校验、竞态条件以及其他设计问题,也依然可能存在。

新驱动的优势并不是永远不会出问题,而是某些类型的错误从一开始就更难被引入。

对于处在 Android 进程通信核心位置的驱动来说,这个优势很实在。

首先得成为一个合格的替代版本

用 Rust 写出新实现,只是开始。

新驱动需要支持 Android 依赖的功能,在实际工作负载下行为正确,性能也要足以替代原有实现。

它还得满足内核开发中的实际要求:代码审查、测试、缺陷修复、兼容性,以及与 Linux 内核其他部分的集成。

Rust Binder 驱动经过数年开发,Alice Ryhl 是其中的主要贡献者之一。在 C 实现退役之前,它就已经合入 Linux 主线内核。

这里的重要里程碑是功能对齐。

功能对齐意味着,新实现支持旧实现中需要保留的相关能力。如果做不到这一点,移除原驱动就可能让系统失去依赖的功能。

项目还报告了有竞争力的性能。根据移除公告,在测试中,Rust Binder 可以达到 C 实现的性能,有时甚至更快。这个结果说明,在相关测试中,Rust 版本的性能足以与 C 实现竞争,但一定不能据此断言 Rust 在所有情况下都比 C 快。

性能取决于工作负载、具体实现、编译器、配置和测量方法。

更有依据的结论是:Rust 实现已经足够成熟,维护者不必再把它仅仅当作实验性的备选方案。

Linux 内核具体改了什么

名为 binder: rm -f binder.c 的移除补丁删除了旧 C 实现,并调整了相关内核构建配置,改用 Rust 版本。

补丁从 drivers/android/binder.c 中删除了 7,000 多行代码。根据补丁讨论,整个变更涉及 20 个文件,共删除 11,470 行。

这个改动让项目不必再与 Rust 实现并行维护这么多旧代码。

不过,删除行数不能直接用来衡量安全性或代码质量的提升。架构上更重要的变化是,项目不再需要维护同一个驱动的两套独立实现。

并行维护会带来额外工作:缺陷可能需要修复两次,新功能可能出现分歧,测试也必须覆盖两个版本之间的差异。

只保留一套实现后,后续 Binder 开发就可以集中到同一份代码上。

为什么需要 Rust

内核代码与普通应用代码不同。

桌面应用崩溃后,可能重启应用就行了。严重的内核故障却可能影响整个操作系统。内核驱动中的安全漏洞,也可能让攻击者获得原本没有的权限。

Binder 尤其重要,因为它负责协助 Android 进程通信,而这些进程可能拥有不同的权限级别。

用一个简化的例子来看。

假设某个驱动跟踪一个被多个进程使用的对象。一个操作释放了对象,另一个操作却仍然认为它还存在。

如果实现没有正确处理对象的生命周期,第二个操作就可能访问已经失效的内存。

在 C 中,要防止这种释放后使用问题,就需要仔细地手动管理生命周期和同步。

Rust 的所有权和借用规则,可以在安全代码中阻止许多违反内存生命周期约束的操作。它的类型系统也能明确表达某些关系,不必完全依赖开发者自觉遵守约定。

这并不能解决所有内核安全问题。驱动仍然需要正确的同步、校验、访问控制,以及对不可信输入的处理。unsafe 代码同样需要仔细审查。

不过,在编译期阻止某些类型的内存错误,确实可以减轻开发者和审查者的负担。

Binder 的实践说明,这些保护能够用于真实的、对性能敏感的内核代码,而不只是小型演示程序。

Android 会变成一个基于 Rust 的系统吗

不会。

这次变化针对的是 Binder。Android 仍然依赖大量 C 和 C++ 代码,Linux 内核本身也依然是一个多语言项目。

Rust 在内核中的作用正在扩大,但这不意味着所有现有驱动都会被重写。

每个子系统都有自己的需求、维护者、历史和约束。有些组件适合用 Rust,有些则未必值得重写。

还要区分内核源码的变化与设备上的实际部署。

移除 C 实现,意味着后续内核开发转向 Rust Binder。但某台 Android 设备具体采用哪个版本、什么时候采用,取决于它的内核和厂商软件。这并不意味着每台 Android 手机都会立刻收到更新。

Linux 内核的重要维护者 Greg Kroah-Hartman 在补丁讨论中欢迎这次移除。他在后续的 char/misc 拉取请求中表示,Rust 版本已经稳定,后续将用于"数十亿台设备"。这句话反映的是 Binder 庞大的部署规模,并不是说所有这些设备已经同时完成切换。

学到什么

你可别一有机会就选 Rust,还是得针对具体的工程问题,评估更换语言是否值得。

Binder 的替代实现必须满足几个要求:

  • 正确性: 保留应用和系统服务依赖的功能。
  • 安全性: 降低遭遇某些类型内存安全错误的风险。
  • 性能: 在相关工作负载下保持竞争力。
  • 可维护性: 让后续修改更容易实现和审查。
  • 兼容性: 与现有内核及 Android 基础设施集成。

Rust 实现之所以能成为可行的替代方案,是因为项目花时间逐步满足了这些要求。

比起语言流行度排名,或对未来的种种预言,这样的实践更有说服力。

如果你也在考虑把 Rust 引入自己的项目,同样可以遵循这个原则:先找到真实的风险来源或维护成本,再明确新实现必须保留哪些特性。在移除旧代码之前,根据这些要求测试替代版本。

重写不自动等于改进。成功的替换,要能证明自己的价值。

Rust 正在迈出下一步

早期围绕 Linux 内核引入 Rust 的讨论,很多都集中在一个问题上:这门语言到底能不能集成进来?

这是重要的第一步。内核开发者需要相应的基础设施、抽象和规则,让 Rust 代码能够与已有的 C 代码共存。

但加入一门新语言,和证明它能替换一个成熟实现,是两回事。

Binder 是一个更具体的里程碑:替代版本已经实现功能对齐,已经在 Android 设备上使用,现在也成为后续开发的重点。

支撑这个决定的,是此前的工程实践。在旧实现退役之前,Rust 版本经历了开发、测试、维护,以及与现有驱动的比较。

这不能证明每个内核子系统都应该走同一条路。但它说明,至少对一个重要子系统而言,Rust 已经成为一个切实可行的选择,可以替代对复杂 C 实现的持续维护。

C 不会从 Linux 中消失。Rust 也不是解决软件安全问题的万能方案。一次成功的迁移,更不能保证今后的每次迁移都会成功。

但 Binder 的这次决定表明,Rust 在系统编程中的角色已经超出了实验阶段。

这说明,开发者已经足够信任一个 Rust 实现,愿意停止开发那个沿用了多年的 C 版本。

以后要是还有人说 Rust 是纸上谈兵,那我就先把这篇文章甩给他!

相关推荐
嵌入式-老费2 小时前
esp32开发与应用(题外话之ADB和Android NDK开发)
android·adb
野生的码农2 小时前
能工智人,40 大寿,尚能班否?
android·ai编程
事圆则缓2 小时前
Android 串口通信:从 /dev/ttyS1到协议帧
android
java1234_小锋2 小时前
【技术专题】CSS3 网页技术 - CSS3 基础样式
android·前端·css3
tongyiixiaohuang11 小时前
WMS已发货状态反写金蝶云星空:单策略实战教程
android
好的佩奇12 小时前
Dart 之类修饰符
android·flutter·dart
alexhilton14 小时前
用Konsist与Lint强制执行设计系统契约
android·kotlin·android jetpack
mounter62517 小时前
深入理解 gccrs:GCC 如何实现 Rust 编译器,以及编译 Linux 内核面临的挑战
linux·驱动开发·rust
北京自在科技18 小时前
谷歌安卓 Gemini 迎来界面改版,Find Hub 接入 Gemini 支持物品记忆查找
android·安卓