Rust 中的不安全的程式碼

unsafe 在 Rust 中是危險,但有時必要的逸出障礙。編寫或查看 unsafe 程式碼時,請務必:

  • 清楚識別每個 unsafe 區塊所需的所有假設和不變情形;
  • 確保符合這些假設
  • 確保符合這些假設持續

為確保日後編輯器不會損毀 unsafe 不變量,每次使用 unsafe 時都必須搭配一個清楚簡潔的註解,說明假設要做出什麼假設。

請盡可能將不安全的內容封裝為單一函式或模組,為外部環境提供安全的抽象化機制。FFI 呼叫通常應透過安全函式公開,該函式的唯一用途就是為相關函式提供安全的包裝函式。這些函式應包含含有下列資訊的註解 (如適用):

  • 先決條件 (例如引數的有效狀態為何?)
  • 失敗處理 (例如應釋出哪些值?忘記哪些值?已失效?)
  • 成功處理 (例如:建立或使用哪些值?)

例子:

impl Channel {
    /// Write a message to a channel. Wraps the
    /// [zx_channel_write](//docs/zircon/syscalls/channel_write.md)
    /// syscall.
    pub fn write(&self, bytes: &[u8], handles: &mut Vec<Handle>)
            -> Result<(), Status>
    {
        let opts = 0;
        let n_bytes = try!(usize_into_u32(bytes.len()).map_err(|_| Status::OUT_OF_RANGE));
        let n_handles = try!(usize_into_u32(handles.len()).map_err(|_| Status::OUT_OF_RANGE));

        // Requires that `self` contains a currently valid handle or ZX_HANDLE_INVALID.
        // On success, all of the handles in the handles array have been moved.
        // They must be forgotten and not dropped.
        // On error, all handles are still owned by the current process and can be dropped.
        unsafe {
            let status = sys::zx_channel_write(self.raw_handle(), opts, bytes.as_ptr(), n_bytes,
                handles.as_ptr() as *const sys::zx_handle_t, n_handles);
            ok(status)?;
            // Handles were successfully transferred, forget them on sender side
            handles.set_len(0);
            Ok(())
        }
    }
}

如果 unsafe 程式碼依賴其他安全程式碼來確保正確性,註解必須與對應的安全程式碼一併保留,指出必須保留哪些不變項目和原因。依賴多個函式行為的變體會更加謹慎,而跨模組或跨 Crate 不安全的作業需要進一步關注。系統可能會拒絕仰賴第三方 Crate 正確行為的 unsafe 程式碼,且系統一律接受依附於第三方類型內部表示法詳細資料的 unsafe 程式碼。

最後,包含 *const*mutUnsafeCellunsafe 類型的 struct 定義必須包含註解,說明該類型的內部表示方式不變。如果使用 unsafe 類型執行異動,「或者」其別名屬於其他類型的記憶體,則應說明其如何維持 Rust 的「鋸齒 XOR 突變」要求。如果基於安全考量而刻意省略任何 derive 的特徵,則必須保留註解,以防止日後編輯者添加不安全的植入式內容。

凡是新增 unsafe 程式碼或對現有 unsafe 程式碼的任何修改,都必須遵守上述規則。

如要進一步瞭解如何封裝 unsafe 不變性,請參閱 Ralf Jung 的「The Scope of Unsafe」Niko Matsakis 的「Tootsie Pop」模型

不安全的評論

如何針對 Rust 程式碼申請不安全的審查:

  1. Rust>Unsafe 元件下回報錯誤。在錯誤說明中附上評論的連結。
  2. 將「Fuchsia Rust Unsafe Review fuchsia-rust-unsafe-reviews@google.com」新增為 CL 的評論者。系統會隨機選擇一名審查人員,並指派對方指派給您的 CL。

如果您的審查具時效性,請提高問題的優先度,並留言說明您的情況。