unsafe
是危險項目,但有時在 Rust 中卻可能需要逃脫攻擊。
編寫或查看 unsafe
程式碼時,請務必:
- 明確指出每個 Pod 所需的
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 不安全
並吸引更多注意力取決於 unsafe
程式碼的正確行為
第三方 Crate 可能會遭拒,且 unsafe
程式碼取決於
有關第三方類型的內部聲明細節,一律不會
接受。
最後,包含 unsafe
類型的 struct
定義,例如 *const
、
*mut
或 UnsafeCell
必須包含說明內部資料的註解
表示物件種類如果使用 unsafe
類型來執行
變異;如果它在另一種型別內為記憶體建立別名,則應該
說明其如何維持 Rust 的「別名 XOR 變異」Google Cloud 就是最佳選擇
如果基於安全考量而刻意省略任何derive
可辨識特徵,
註解,以防止日後編輯者加入不安全的字義。
凡是新增的 unsafe
程式碼或任何
修改現有的 unsafe
程式碼。
如要進一步瞭解如何封裝 unsafe
個不變體,請參閱
Ralf Jung 的《The Scope of Unsafe》和
Niko Matsakis 的《Tootsie Pop》模型。
不安全的評論
如何針對 Rust 程式碼提出不安全的審查要求:
- 透過
Language Platforms > Rust > Unsafe
元件回報錯誤。包含 錯誤說明中的評論連結。 - 新增「Fuchsia Rust 不安全的評論 fuchsia-rust-unsafe-reviews@google.com」 審查人員我們會隨機選擇審查者 加入 CL
如果審查具時效性,請提高錯誤的優先順序,並留下 我們明白您的情況。