unsafe

2018-08-12 22:04 更新

unsafe    

Rust 的主要缺點是其對行為的強大的靜態(tài)擔保。但安全檢查是保守的:有些程序實際上是安全的,但是編譯器無法證實這是真的。為了寫這種程序,我們需要告訴編譯器放寬限制。為此, Rust 有一個關鍵詞,unsafe。代碼使用 unsafe 比正常的代碼有更少的限制?!   ?/p>

讓我們復習語法,然后我們將討論語義。unsafe 在兩種情況下被使用。第一個情況是標記一個函數為不安全:

unsafe fn danger_will_robinson() {
// scary stuff 
}

例如,所有函數調用 FFI 時必須標記為 unsafe。第二個使用 unsafe 情況是不安全塊:

unsafe {
// scary stuff
}

能夠明確劃定可能有漏洞的代碼是非常重要的,并且這些漏洞能造成大問題。如果 Rust 程序段錯誤,你能確定這部分中哪里標記為 unsafe。

“safe”是什么意思?

在 Rust 的上下文中,safe 的意思是“不做任何不安全的事?!?這很簡單!     

好吧,讓我們再試一次:什么是不安全的?這里有一個列表:

  • 數據競爭  
  • 非關聯化空的或懸空的原始指針  
  • 讀取 undef(未初始化的)內存  
  • 打破原始指針的指針別名規(guī)則?! ?/li>
  • &mut T 和 &T 遵循LLVM的作用域 noalias 模式,除非 &T 包含一個 UnsafeCell<U>。不安全的代碼必須不違反這些別名擔保?! ?/li>
  • 在沒有 UnsafeCell<U> 的情況下,改變一個不可變的值/引用
  • 通過這些編譯器特性調用未定義的行為:   
    • 有 std::ptr::offset 的對象的越界索引,除了一個字節(jié)結束過去這是允許的。  
    • 在重疊的緩沖區(qū)時使用 std::ptr::copy_nonoverlapping_memory (memcpy32/memcpy64 特性) 
  • 原始類型的無效值,即使在私有作用域/局部:   
    • 空/懸空的引用或盒子 
    • 在一個 bool 中除了 false (0) 或 true (1) 的值 
    • 在一個不包括類型定義的 enum 的一個判別式
    • 在一個大于或等于 char::MAX 的 char 里的一個值
    • 在一個 str 里的 Non-UTF-8 類型序列 
    • 從外部代碼展開到 Rust 或 從 Rust 展開到到外部代碼。

這是很多東西。注意到各種各樣的不好的但沒有標記為 unsafe 的行為是很重要的。

  • 死鎖  
  • 從私有作用域讀取數據 
  • 由于引用計數周期引起的泄漏  
  • 沒有調用析構函數的情況下退出  
  • 發(fā)送信號  
  • 訪問/修改文件系統 
  • 整數溢出

Rust 不能防止各種各樣的軟件問題。bug 代碼可以并將寫在 Rust。這些行為并不好,但他們不符合 unsafe。

Usafe 超級能力    

在不安全的函數和不安全的代碼塊內,Rust 通常會讓你做三件通常不會做的事。以下就是這三件事:

  • 訪問或更新一個靜態(tài)可變的變量。  
  • 解除引用原始指針?! ?/li>
  • 調用不安全的函數。這是最強大的能力?!   ?/li>

就這樣。重要的是,例如, unsafe 不會“關掉借用查器”。將 unsafe 添加到一些隨機 Rust 代碼并沒有改變其語義,它不會開始接受任何東西?!   ?/p>

但是它會讓你寫一些打破一些規(guī)則的東西。讓我們學習這三種能力。

訪問或更新 static mut

Rust 有一個稱為‘static mut’的特性,它允許可變的全局狀態(tài)。這樣做會導致數據競賽,因此本身是不安全的。有關詳細信息,請參本書的靜態(tài)部分。

解除引用一個原始指針

原始指針讓你做任意指針的運算,會導致許多不同的內存安全問題。在某種意義上,一個任意指針的解除引用的能力是你可以做的最危險的事情。更多關于原始指針,請看本書相關部分。

調用 unsafe 函數

這最后的能力關于 unsafe 的兩個方面:您只能調用一個 unsafe 塊內標記 unsafe 的函數。    

這種能力是強大的。Rust 為 unsafe 函數提供一些編譯器特性,繞過安全檢查和一些安全功能,換來安全速度?!   ?/p>

我將再次重復:即使你可以在 unsafe 塊和函數中做任意事情,并不意味著你應該這樣做。雖然你堅持不變量編譯器仍然將起作用,所以要小心!

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號