11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

Rust 成为 C 的接班人 或将开发 Linux 驱动

  • 2019-09-09
  • 本文字数:2300 字

    阅读完需:约 8 分钟

Rust成为C的接班人 或将开发Linux驱动

Rust 是由 Mozilla 主导开发的专注于安全、速度和并发的系统级编程语言,目前已经逐渐走向成熟。最近,英特尔首席工程师 Josh Triplett 在 2019 年开源技术峰会(OSTS)上发表了主题为“英特尔和 Rust:系统编程的未来”的演讲。他就开发人员是否可以用 Rust 开发驱动程序这一问题询问了 Linux 内核稳定版维护者 Greg Kroah-Hartman。

Kroah-Hartman 表示愿意接受用 Rust 开发 Linux 内核的驱动程序,但有两个条件。其一,以可选的方式存在,而不是默认启用,这样其他开发者就不需要使用 Rust 去构建内核;其二,Rust 驱动需要展现出比 C 驱动更具优势的特性,比如针对内核 API 的安全封装器。看样子,大家未来有很大的机会使用 Rust 编写 Linux 驱动。



在很长一段时间里,Linux 内核和驱动程序开发,基本上都是用 C 语言编写的。


然而,C 写 driver 的主要缺陷在于 C 赋予程序员的自由度过大,所谓能力越大责任越大,程序员需要小心处理各种细节以保证 driver 的安全。在一些情况下,程序员容易因为疏忽大意写出不安全的代码。例如申请的内存忘记释放(内存泄漏),使用了已经被释放的指针(use-after-free),数组越界访问(buffer overflow)等等。这些错误大多归因为 C 是一门不安全的语言。


前段时间,随着微软计划用 Rust 取代 C 和 C++新闻的曝出,Rust 被认为是 C/C++的接班人。由 Mozilla 开发的 Rust 被认为具有较强的安全性。同时,由于特殊的类型系统,Rust 不需要垃圾收集,也被认为是高效的。Rust 程序运行速度极快,可防止段错误并保证线程安全。这些属性使该语言极大地吸引了专注于应用程序安全性的开发人员。香港中文大学系统安全系博士李卓华指出,Rust 主要通过严格的语法和安全检查来限制程序员,“逼迫”程序员写出更安全的代码。例如 Rust 的 ownership 特性保证任何时刻,一个对象最多只有一个可变引用,且在其生命期结束后编译器会自动将其内存释放,从而避免了内存泄漏和 use-after-free 的问题。


《Rust 编程之道》作者张汉东表示,Rust 的优势在于内存安全和并发安全,以及现代化的类型系统,更能保证程序的正确性。并且拥有现代化的工具链,比如对 SIMD、WASM 等的支持。现在已经有人用 Rust 写了 WASM 的虚拟机(Wasmer),允许在 Linux 内核中实现安全的 WebAssembly 运行环境,这样可以避免如系统调用(上下文切换)、用户态/内核态数据复制等性能损耗(当前评测情况是提升 10%)。看得出来,使用 Rust 扩展 Linux 内核,会带来更多的可能性。



北美华人安全论坛 BASec 创始人韦韬认为,Rust 有着出色的性能表现,不过对于普通业务而言,性能不是关键,稳定性才是。这个恰恰是 Rust 的最强项。就稳定性而言,Rust 碾压大部分语言,包括 C,C++,Go,Python,PHP 等等。但是没有免费的午餐,Rust 的稳定性来自于 Borrow Checker 的"严苛",Ownership 机制对于 Rust 入门者有一定的门槛。但大部分情况下,配合上基本的编程规范(严格限制 unsafe/unwrap/…等),只要 Rust 编译器点头,程序运行起来就没什么问题。需要注意的是,Rust 保障的内存安全不包括防止内存泄露。因为内存泄露的语义和具体应用逻辑强相关,所以还需要做额外的内存泄露检查,但这方面的工具比较现成,一般不是大问题。但即使如此,Rust 写驱动也不太乐观,主要是两个原因。一是需要把底层的 unsafe 仔细封装,因为在驱动场景下,很多操作不满足 Rust safe 的要求,一旦代码里混杂了很多 unsafe,那么因常规安全检验工具的缺乏,Rust 反而会不如 C。二是硬件厂家的工程师从 C 改为 Rust 更漫长,广泛的硬件驱动支持才是 Linux 生态繁荣昌盛的根基,这个生态挑战比单纯的技术挑战更大。


就 Rust 目前开发 Linux 驱动的落地难点问题,李卓华列出以下几点:


  1. Linux 内核中定义的函数,结构体众多,想要在 Rust 中使用需要将它们重新改写成对应的 Rust 版本,这一点人工完成的话工作量极大,自动完成的话(用 bindgen 将 C 翻译成 Rust)代码丑陋杂乱,且缺乏安全抽象。

  2. Linux 内核使用的很多 C 的特性没有对应的 Rust 实现,例如 C 结构体的 bitfield。

  3. Driver 主要是底层的代码,有时需要 Rust 的 unsafe 特性,无法保证安全性。

  4. 编写 Driver 主要是提供一组回调函数(callback function),由内核负责在合适的时候调用。这就需要回调函数必须用 FFI(Foreign Function Interface)编写(因为 Linux 内核只提供 C 的函数原型),且必须是全局的(因为要让 Linux 内核可以找到它们),这就限制了开发者封装和组织风格良好的代码。

  5. 调用内核函数也是 unsafe 的,除非为其提供一层安全抽象。

  6. Linux 不保证 API 和 ABI 的稳定性,因此难以封装内核函数和数据结构。


在此前 InfoQ 发表的文章中,有些读者评论 Rust 的生态尚未建立,可能会成为落地的阻碍。对此,韦韬表示,Crate 虽然还不够丰富,但现在逐渐在改善;其实更大的问题是低质量的 Crate 混杂其中,会破坏 Rust 应用的稳定性和安全性。但相比较而言,Rust 的 crate 包管理比 C/C++强太多,已经有很多落地实践表明是完全可行的。


关于人们关心的如何为 Linux 的内核函数提供一层安全的抽象的问题。专家认为,这里存在不少挑战,但是是一个正确的方向,这个方向如果成功,会极大的提升 Linux 内核的安全性和稳定性。


感兴趣的 Rust 开发人员不必从头开始。目前至少有一个Github项目已经存在,它适用于内核模块的框架,有关该项目的背景信息可以在 2019 年 Linux 北美安全峰会的演示文稿中获取。


相关链接:


Rust is the future of systems programming, C is the new Assembly (Packt)


Securing the Device Drivers of Your Embedded Systems:Framework and Prototype


lizhuohua/linux-kernel-module-rust


2019-09-09 14:087267
用户头像
王文婧 InfoQ编辑

发布了 126 篇内容, 共 66.7 次阅读, 收获喜欢 269 次。

关注

评论

发布
暂无评论
发现更多内容

第七期总结

GAC·DU

redis 基础-数据结构-跳跃表

小技术君

第七周总结

上山砍柴

第07周 优化系统性能-01 学习总结

Jaye

Python 实现 RabbitMQ 的六种工作模式(附 Python 代码)

AlwaysBeta

Python RabbitMQ 消息队列

架构师 0期07周总结

我在终点等你

性能测试并发压力变大,系统如何变化

李朋

第7周

Geek_2b3614

Mac 环境下 RabbitMQ 的安装

AlwaysBeta

Mac RabbitMQ 消息队列

架构师培训 -07 总结 性能测试与性能优化

刘敏

架构师训练营第七周总结

一剑

架构师训练营学习总结7——性能测试与优化

默默

week7总结

雪涛公子

并发测试JAVA

王麒宇

第7周 性能优化:性能优化是架构师展现自己技术全面性的时刻

陆不得

架构师训练营 - 作业 7

进击的炮灰

week 7 作业

a晖

ARTS打卡Week 08

teoking

ios LeetCode

架构师训练营 week7

devfan

架构师训练营 No.7 周总结

连增申

关于性能压测

俊俊哥

性能测试

架构训练营第七周感悟

张锐

Vue3-组合式API

福豆粑粑

Vue3

第07周 优化系统性能-01 命题作业

Jaye

操作系统、性能优化

GalaxyCreater

性能优化

redis系列之——数据类型geospatial:你隔壁有没有老王?

诸葛小猿

redis geospatial

架构师训练营第七周总结

Bruce Xiong

第七周总结

Geek_a327d3

第七周作业

Geek_a327d3

【架构师训练营 - week7 -1】作业

早睡早起

RabbitMQ 的监控(附 Python 监控源码)

AlwaysBeta

Python RabbitMQ 消息队列 消息堆积处理

Rust成为C的接班人 或将开发Linux驱动_编程语言_王文婧_InfoQ精选文章