科學家們正將C語言分解,以便將程式碼轉換為Rust

導讀:法國國家資訊和自動化研究院 (Inria) 和微軟的計算機科學家們設計出一種方法,可以自動將 C 程式碼子集轉換為安全的 Rust 程式碼,以滿足日益增長的記憶體安全需求。
C 程式語言誕生於 20 世紀 70 年代初,用於構建許多關鍵型系統、應用程式和庫。例如,Linux 核心主要是用 C 語言編寫的。
但 C 語言和它的擴充套件 C++ 一樣,並不是為記憶體安全而設計的,它採用手動記憶體管理,比自動記憶體管理(例如垃圾回收)更高效、更靈活,但也更容易出現記憶體錯誤。
近期的多項研究表明,記憶體安全錯誤(如越界讀寫和釋放後使用)佔軟體漏洞的大多數。在谷歌的 Android 作業系統中,它們在 2019 年佔漏洞總數的 76% ,而 Chocolate Factory 預測,透過使用 Rust 和安全編碼實踐,到 2024 年底,這一數字將降至 24% 。
Rust 程式碼可以編寫為記憶體安全的或不安全的應用,這由開發人員自行決定。雖然 C 和 C++ 程式碼可以透過勤奮、靜態分析和測試變得更加記憶體安全,但這兩種程式語言都沒有提供開箱即用的記憶體安全保證。
過去幾年,業界與政府一直在努力減少 C 和 C++ 程式碼的使用,增加使用記憶體安全的程式語言,如 Rust、Go、Python 和 Java(儘管這些語言可能連結到不安全的庫)。正如網際網路安全研究小組 (ISRG) 的 Prossimo 專案所說:“使用 C 和 C++ 對社會有害,對你的聲譽有害,對你的客戶也有害。”
並不是每個人都會走得這麼遠。許多 C 和 C++ 程式設計師寧願找到繼續使用他們喜歡的工具的方法,而不是加入 Rust 大潮,甚至谷歌這樣的大廠,作為 Rust 最直言不諱的佈道者之一,也承認 C 和 C++ 程式碼將長期存在。
因此,我們付出了相當大的努力來開發使 C 和 C++ 更加記憶體安全的方法,並開發像DARPA 的 TRACTOR程式這樣的自動程式碼轉換機制。
像TrapC和Fil-C這樣的努力使 C 記憶體安全,但也有其弊端。TrapC 仍在開發中,專注於語言的一個子集。Fil-C 目前會對效能造成影響,並且缺乏完整的應用程式二進位制介面 (ABI) 相容性。
在一篇題為《將 C 編譯為安全的 Rust,形式化》的論文中,作者 Aymeric Fromherz(Inria)和 Jonathan Protzenko(Microsoft)提供了一種替代自動將 C 轉換為 Rust 的方案 ,該方案會產生不安全的Rust。他們的重點是為經過形式化驗證的工業級程式碼提供轉換路徑。
“C 允許程式設計師在別名、低階強制型別轉換、記憶體管理和資料表示方面發揮創造力,”作者解釋道。“在 Rust 中表達這些模式需要放棄許多靜態保證,以便允許未經檢查的別名、表示之間的強制型別轉換(在 Rust 術語中也稱為‘變形’)等,這是透過 Rust 的不安全特性實現的。但這樣做會抹殺 Rust 的優勢!
因此,Fromherz 和 Protzenko 開發了 C 的一個子集,稱為“Mini-C”,它避免了常見的 C 模式和特性,例如指標演算法和隱式可變性,這些特性無法直接轉換為安全的 Rust。
透過使用KaRaMeL編譯器框架實現 Mini-C ,科學家們表示他們的方法可以生成安全的 Rust 程式碼,但需要注意的是可能需要進行一些重構。
他們解釋說:“我們不會將 C 語言的全部通用性自動轉換為不安全的 Rust 語言,並試圖使生成的程式碼更安全,而是以面向資料的 C 語言應用子集為目標。因此,我們的翻譯過程是半主動的:使用者可能必須對源 C 程式進行最小的調整,以適應支援的語言子集;一旦進入這個子集,我們的方法就會自動生成有效、安全的 Rust 程式碼。”
他們在 HACL*(高保證加密庫)上測試了轉換過程,HACL* 是一個由 80,000 行 C 程式碼組成的經過驗證的加密庫,而在 EverParse 上,EverParse 是一個由 1,400 行 C 程式碼組成的經過驗證的格式化程式和序列化程式庫。
HACL* 轉換隻需要最少的程式碼更改,而 EverParse 轉換無需更改原始碼即可完成。他們聲稱,結果效果很好 – 儘管添加了胖指標和執行時邊界檢查,Rust 程式碼仍表現出與原始 C 程式碼相同的效能特徵。
這項工作現在有助於使各種依賴應用程式更加安全。作者表示,他們用 Rust 編譯的 HACL* 已打包在 libcrux 加密庫中,其中部分內容已新增到 Mozilla 的NSS和 OpenSSH 中。

作者:聆聽音樂的魚

相關閱讀:

相關文章