解法
浏览器信任解析陌生人制作的媒体文件的代码,攻击者反复利用这些格式针对解码器的内存漏洞。Mozilla赞助Rust近七年,Rust被构想为C++的安全替代品,但到2016年年中,Firefox中还没有任何Rust代码;这种安全优先的语言仍需在庞大且性能关键的C++浏览器中证明自己。
保护用户的明显方式都有缺陷。修补C++解析器意味着要永远防御每个新漏洞;沙箱化只能缩小爆炸半径,不能消除漏洞类型;而用Rust重写整个浏览器是一项多年的冒险,可能会在迁移过程中破坏产品。Mozilla的媒体播放团队反而选择了一个有界限且安全关键的组件:处理不可信网络媒体的mp4元数据解析器。
Ralph Giles和Matthew Gregan用纯Rust编写了该解析器的替代品,通过C API暴露,使周围的C++构建不受影响,并验证其产生与原有代码相同的结果。Firefox 48随后将其带到所有桌面平台,首次让生产级Rust面对数亿用户,Android支持计划随后进行。
这次试点之所以成功,是因为它将意识形态转化为证据。Rust的编译时规则消除了该组件的内存漏洞类型,而不是增加另一层防御,Firefox遥测记录显示,新代码在超过十亿次使用中零问题。Mozilla称这是第一步,而非终点:一个经过验证的模板——替换风险最大的有界组件,证明一致性,发布,并测量——为更大的迁移铺路。
What it achieved
从处理不可信数据的解析器开始迁移
为什么有效
媒体解析是不可信字节与原生代码相遇之处,因此试点针对每行剩余的最大风险
自包含的解析器有清晰的测试边界:可以检查与C++组件相同的结果
编译时内存安全消除了整个漏洞类型,而不是增加防御层
十亿次使用中零遥测问题将语言赌注转化为可衡量的生产证明
通过C API暴露Rust使解析器在不干扰其他C++构建的情况下发布
可以借鉴什么
将新技术引入遗留代码库是移植,不是重写:选择风险最大且边界可测的组件,发布它,让生产数据为更大规模提供理由
后续
Firefox 48将首个生产级Rust带给所有桌面用户,Mozilla将此里程碑视为开场而非终点:Oxidation wiki规划了每个平台上的Rust功能及时间,Bugzilla 1284816追踪使Rust成为Firefox构建的必需部分。发布期间发现的低内存崩溃通过使用可回退的线程构建器API(返回错误而非崩溃)修复,并包含在Firefox 48中。同样的路径——有界的内存安全替换并经过遥测验证——成为后续Rust组件的蓝图。
从这里,追溯依据
参考来源
- Shipping Rust in Firefox hacks.mozilla.org
- mozilla/mp4parse-rust — Parser for ISO Base Media Format aka video/mp4 written in Rust github.com