審計 Bun 的 Rust 移植:在 13,000 個 unsafe 區塊中導航

將高效能執行環境從一種系統語言轉移到另一種系統語言,往往不是一件簡單的事。Bun 最初是以 Zig 撰寫,現在正進行移植至 Rust——此舉在最近發布一份全面且具爭議性的程式碼庫審計後,受到密切關注。

在 Rust 移植正式發布之前,Bun 團隊進行了預發布檢查,以量化與分類 unsafe 區塊的使用情況。結果相當驚人:目前的移植包含 13,365 個 unsafe 區塊。雖然數量龐大,審計的目標是提供一條減少這些技術債務的路線圖,讓程式碼在投入生產使用前先行優化。

拆解 13,365 個 unsafe 區塊

Rust 程式碼庫中大量的 unsafe 區塊常會讓開發者警鐘大作,因為 unsafe 代表編譯器的安全保證被暫停。然而,Bun 的審計認為,這些區塊大多不是根本缺陷,而是移植過程的副產品。

根本原因

根據審計,約三分之二的 unsafe 位置來源於三個主要因素:

  1. Zig 移植: 許多所有權慣例與模式直接從原始的 Zig 實作搬過來。
  2. FFI 邊界: 為了與 C/C++ 函式庫及外部引擎介面,必須使用的 unsafe 區塊。
  3. 效能: 少部分(約 3%)的 unsafe 區塊是刻意使用,以爭取極致效能。

通往安全之路

Bun 的目標不是要消除所有 unsafe 程式碼——對於與低階系統 API 互動的執行環境而言,這幾乎是不可能的——而是盡量減少。審計將這些區塊分為兩大類結果:

  • 可取代(約 9,300 個位置): 這些區塊可以轉換為安全的 Rust 程式碼。審計指出 raw *mut Self 狀態機與 &self 轉為 &mut 的轉型等模式是主要的移除目標。
  • 永久(約 4,000 個位置): 這些區塊將保留 unsafe,但計畫是將它們包裝在安全抽象層中,以確保安全的 Rust 不會觸發未定義行為(UB)。

安全性 vs. 數量

審計最關鍵的發現之一是發現了五個根本 不安全 的函式。這些情況是指未定義行為可以從安全的 Rust 被觸發——實際的錯誤與 13,365 個 unsafe 區塊無關。審計的首要任務是先修補這些安全性漏洞,再處理 unsafe 區塊的總數。

社群反應:「AI 產物」與技術懷疑

儘管有詳細的拆解說明,該公告在 Hacker News 上仍遭到開發者社群的強烈反彈。大部分批評聚焦於審計頁面被標示為「AI 生成」,因而引發指控,認為整個移植可能是 AI 驅動的翻譯產物,而非人工工程。

批評者對於如此龐大清理工作所需的移植表示懷疑,質疑其可信度。正如一位評論者所說:

"這個移植是 AI 產物,充斥著 13k 個 unsafe 區塊。而這篇部落格文章更是 AI 產物,聲稱提供一個「計畫」來減少這個數字。"

其他開發者質疑一次性完整移植複雜系統的明智性,認為採取漸進式方法——將個別元件遷移至生產環境並單獨測試——會更為穩妥。

結論

Bun 的 Rust 移植是一項大規模的語言遷移實驗。透過公開 unsafe 區塊的數量並提供公開審計,Bun 試圖展現對 Rust 安全保證的承諾。然而,高 unsafe 數量與「安全」實作之間的差距仍相當大,社群的回應也顯示,移植過程中累積的技術債務可能是一個必須克服的重大障礙。

Sources