10 月,开发者不可错过的开源大数据大会-2021 WeDataSphere 社区大会深圳站 了解详情
写点什么

Rust 大步跨入 Android 平台

2021 年 4 月 08 日

Rust大步跨入Android平台

近日,谷歌宣布 Android 开源项目(AOSP)现在支持 Rust 编程语言来开发 OS。这一举动将让正火的 Rust 语言热度再次上涨。

内存安全错误

目前,C 和 C++的内存安全错误仍然是不正确性来源中最难解决的问题。


谷歌指出,内存安全错误是稳定性问题的罪魁祸首,它在 Android 严重安全漏洞中长期占据大约 70%的比例。


Android 操作系统广泛使用 Java,以有效保护 Android 平台的大部分内容免受内存错误的影响。但不幸的是,系统中比较低级的层是不能选择 Java 和 Kotlin 的。



OS 中的较低级别需要的是系统编程语言,如 C、C++和 Rust 等。这些语言设计时考虑到了可控和可预测性的目标。它们提供对低级系统资源和硬件的访问。它们的资源需求相对轻量,并具有更可预测的性能特征。


对于 C 和 C++,开发人员负责管理内存的生命周期。但是,这样做很容易出错,尤其是在复杂的多线程代码库中更是如此。


Rust 使用编译时检查(强制执行对象生命周期/所有权)和运行时检查(确保内存访问有效)的组合来提供内存安全保证。提供这种安全性的同时,Rust 的性能表现足以匹敌 C 和 C++。


谷歌表示,“除了正在进行和即将到来的改进内存错误检测的措施外,我们还在进一步努力设法防患于未然。内存安全语言是预防内存错误的成本效益最优的手段。”

沙箱的局限性

谷歌披露,所有 Android 进程均已沙箱化。它们通过遵循三选二规则(Rule of 2)来确定功能是否需要额外的隔离和特权。这种规则很简单:给定三个选项,开发人员只能选择以下三个选项中的两个。



对 Android 来说,这意味着如果代码是用 C/C++编写并解析了不可靠的输入,则应将其包含在一个严格受限和无特权的沙箱中。


遵守三选二规则的好处是可以有效降低安全漏洞的严重性和暴露程度,但是它也存在一些局限:


  • 沙箱的成本很高。它需要的新进程会消费额外的开销并引入延迟,这是由于 IPC 和额外的内存占用导致的。

  • 沙箱无法消除代码中的漏洞。高漏洞密度会降低其有效性,让攻击者可以将多个漏洞链接在一起。


像 Rust 这样的内存安全语言可以通过两种方式来克服这些限制:


  • 降低代码中错误的密度,从而提高当前沙箱的效率。

  • 减少谷歌对沙箱的需求,从而引入更安全、更省资源的新特性。

近 50%的错误出现短于一年

根据分析,大多数内存错误出现在新的或最近修改的代码中,大约有 50%错误出现还不到一年。



因此,谷歌表示,“我们在内存安全语言方面的工作最好专注于新开发的代码,而不是重写成熟的 C/C++代码。并且,引入一种新的编程语言并不能解决我们现有 C/C++代码中的错误。即便我们重新分配 Android 团队中所有软件工程师的工作,要重写几千万行代码也是完全不可行的。“


相比之下,较旧的内存错误很少见,很多人可能会觉得很惊讶。谷歌还发现,较旧的代码并不是亟需改进的。"随着时间的推移,软件错误会被逐渐发现和修复,因此我们可以预期还在维护但未处于活跃开发状态的代码中的错误量会逐渐减少"。


谷歌还指出,对于复杂的 C/C++代码库来说,通常只有少数人能够开发和审查错误修复,而且即使花费大量精力来修复错误,有时修复本身也会是不正确的。


当错误相对少见且危险的错误得到优先关注时,错误检测才是最有效的。为了获得从错误检测中获得的改进所带来的好处,谷歌称“首先防止引入新的错误”。

预防为主

Rust 语言实现了一系列现代化的语言特性,从而提高了代码的正确性:


  • 内存安全性:搭配编译器和运行时检查来增强内存安全性。

  • 数据并发:防止数据争用。它让用户能轻松编写高效、线程安全的代码,也让 Rust 打出了“无畏并发”的口号。

  • 更具表现力的类型系统:帮助防止逻辑编程错误(例如 newtype 包装器、带有内容的 enum 变体)。

  • 引用和变量是默认不可变的:帮助开发人员遵循最小特权的安全原则,仅在实际需要时才将引用或变量标记为可变。C++有常量,而且倾向于偶尔且不一致地使用常量。相比之下,Rust 编译器会为永不突变的可变值提供警告,来帮助避免散乱的可变性注释。

  • 标准库中更好的错误处理:将 Result 中可能失败的调用包装起来,于是编译器会要求用户检查失败,即使是未返回所需值的函数也是如此。这样就避免了 RageAgainstCage 之类的漏洞,这种漏洞是来源于未处理错误的。Rust 简化了通过?运算符传播错误的过程,并优化了 Result 以降低开销,从而鼓励用户以相同的样式编写易错的函数并获得相同的保护。

  • 初始化:要求所有变量在使用前都初始化。未初始化的内存漏洞一直是 Android 上 3-5%的安全漏洞的源头。在 Android11 中,谷歌开始在 C/C++中自动初始化内存以减少这种问题。然而,初始化到零并不总是安全的,尤其是对于返回值这样的事物,因为它可能成为新的错误不当处理来源。而 Rust 要求每个变量在使用前都要初始化为该类型的合法成员,避免了无意初始化为不安全值的问题。类似 Clang for C/C++,Rust 编译器意识到了初始化的要求,并避免了双重初始化的所有潜在性能开销。

  • 更安全的整数处理:默认情况下,Rust 调试版本会启用溢出清理功能。如果程序员确实打算让一个计算溢出,则鼓励他们指定一个 wrap_add;否则,则指定一个 saturating_add。谷歌打算为 Android 的所有版本启用溢出清理功能。此外,所有整数类型转换都是显式转换:在分配给变量或尝试对其他类型进行算术运算时,开发人员不会在函数调用期间意外地转换。


据悉,在过去 18 个月中,谷歌一直在向 Android 开源项目增加对 Rust 的支持。不过,它也坦言,”在 Android 平台上添加新语言是一项艰巨的任务。不仅需要维护很多工具链和依赖项,更新测试基础架构和工具链,还要培训开发人员“。


谷歌称,未来几年计划将 Rust 扩展到 OS 的更多部分。

2021 年 4 月 08 日 13:594034
用户头像
万佳 InfoQ编辑

发布了 624 篇内容, 共 238.5 次阅读, 收获喜欢 1601 次。

关注

评论 1 条评论

发布
用户头像
现在各大操作系统背后的组织或企业都支持Rust,可见如果C++不做出一些改变(如增加一些类似的避免内存问题的模型)。被替代是迟早的事了.
2021 年 04 月 09 日 15:33
回复
没有更多了
发现更多内容

你真的了解敏捷吗?听马丁福勒聊敏捷

涛哥

敏捷 数字化转型

游戏夜读 | 最常见的两种类型

game1night

如何写出高质量的代码?(浅谈代码规范、重构、单元测试的重要性)

Nick

单元测试 重构 代码重构 代码规范

当你输入get/set命令的时候,Redis做了什么

老胡爱分享

redis 源码分析

还在埋头干活?给程序员的几个忠告

四猿外

Java 深度思考 程序员 随笔杂谈

运营系统架构文档

师哥

重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」

小傅哥

设计模式 小傅哥 重构 代码优化 责任链模式

架构师训练营作业 (第三周)

王海

极客大学架构师训练营

数据库如何弹性伸缩?

Aaron_涛

数据库 架构 云原生

培训机构出来的程序员常被鄙视,招谁惹谁了

程序员生活志

程序员 程序人生

Facebook 起诉水军公司:删不过来,我还告不过来吗?

神经星星

facebook 亚马逊云 AWS Lightsail 水军 虚假评论

思想不进化的人都是可怜人

Neco.W

提升认知 思考 进步 进化

【写作群星榜】6.12~6.19 写作平台优秀作者 & 文章排名

InfoQ写作平台官方

写作平台 排行榜

flutter开发

InfoQ_1c4a1f813eb1

第三周作业

LEAF

Free space——区块链加密社交平台新秀之作

Geek_116789

如何让企业的IT数据运维更有“烟火气”?

博睿数据

数据挖掘 学习 数据中台 运维 大屏可视化

必知必会,程序员都应该会的Linux的50个知识点!

Java小咖秀

Linux 面试 运维 Shell 经验

GitHub 热榜:一款堪称作业终结者的开源神器!

JackTian

GitHub 开源 工具类网站 学生党 Text-to-handwriting

常年“佛系”Crysis勒索病毒突然变种 变身黑客工具合辑

360安全卫士

Zoom 妥协!对免费用户开放端到端加密服务

神经星星

音视频 Zoom 端到端加密 隐私保护 数据保护

架构师训练营-week01 学习总结

GunShotPanda

加密与解密

返町

一种极致性能的缓冲队列

捉虫大师

Java 性能

对不起,我爱你

小天同学

小说 爱情 情感

互联网人的娱乐精神之28岁退休 & P8和生活助理的故事

码农神说

程序员 漫画 退休

为什么Web开发人员在2020年不用最新的CSS功能

Geek_Willie

CSS

英特尔宋继强:坚持科研的长期主义 推动AI向3.0时代跃迁

最新动态

跨云厂商部署 k3s 集群

米开朗基杨

k3s wireguard

小师妹学JVM之:JIT中的LogCompilation

程序那些事

JVM 「Java 25周年」 小师妹 性能调优 JIT

Android APP启动白屏优化

小菜鸟学php

android白屏

Rust大步跨入Android平台-InfoQ