Home >> Blog >> 什麼是 競爭危害 Race condition ?
什麼是 競爭危害 Race condition ?
什麼是競態條件?
競爭條件是當設備或系統嘗試同時執行兩個或多個操作時發生的不希望的情況,但由於設備或系統的性質,必須以正確的順序執行操作才能正確完成.
競爭條件最常與計算機科學和編程相關聯。當兩個計算機程式進程或線程試圖同時訪問相同的資源並導致系統出現問題時,就會發生這種情況。
競爭條件被認為是多線程應用程式的常見問題。
什麼是競爭條件的例子?
競爭條件的一個簡單示例是電燈開關。在一些家庭中,有多個電燈開關連接到一個普通的天花板燈。當使用這些類型的電路時,開關位置變得無關緊要。如果燈亮著,將任一開關從其當前位置移動會關閉燈。同樣,如果燈關閉,則將任一開關從其當前位置移開即可打開燈。
在計算機內存或存儲中,如果幾乎在同一時刻接收到讀取和寫入大量數據的命令,並且機器嘗試覆蓋部分或全部舊數據,而舊數據仍在執行中,則可能會出現競爭條件。讀。結果可能是以下一項或多項:
- 計算機崩潰或識別程式的非法操作
- 讀取舊數據時出錯
- 寫入新數據時出錯
如果指令以不正確的順序處理,也會出現競爭條件。
假設兩個進程需要在特定的內存位置執行位翻轉。正常情況下,操作應如圖 1 所示。
如果發生競爭條件導致這兩個進程重疊,則操作序列可能看起來更像圖 2 中所示的內容。
當輸入發生衝突時,邏輯門中偶爾會出現競爭條件。由於門輸出狀態需要有限的非零時間來對輸入狀態的任何變化做出反應,因此門後的敏感電路或設備可能會被輸出狀態所欺騙而無法正常工作。
競態條件有哪些類型?
有幾種類型的競爭條件。定義競爭條件對系統的影響的兩個類別稱為關鍵和非關鍵:
- 嚴重的競爭條件將導致設備、系統或程式的最終狀態發生變化。例如,如果同時翻轉連接到公共燈的兩個電燈開關會燒毀電路,則認為這是一個關鍵的競爭條件。在軟件中,關鍵的競爭條件是當某種情況導致具有不可預測或未定義行為的錯誤時。
- 非關鍵競爭條件不會直接影響系統、設備或程式的最終狀態。在燈的示例中,如果燈關閉並且同時翻轉兩個開關打開燈並且與翻轉一個開關具有相同的效果,則它是非關鍵競爭條件。在軟件中,非關鍵競爭條件不會導致錯誤。
關鍵和非關鍵競爭條件不僅限於電子或編程。它們可能發生在發生競爭條件的許多類型的系統中。
在編程中,兩種主要類型的競態條件發生在代碼的關鍵部分,即由多個線程執行的代碼部分。當多個線程嘗試讀取一個變量,然後每個線程都對其進行操作時,可能會出現以下情況之一:
- 讀-修改-寫。當兩個進程讀取程式中的一個值並寫回一個新值時,就會發生這種競爭情況。它通常會導致軟件錯誤。與上面的示例一樣,期望兩個進程將順序發生——第一個進程產生它的值,然後第二個進程讀取該值並返回一個不同的值。
例如,如果對支票賬戶的支票是按順序處理的,系統將首先確保賬戶中有足夠的資金來處理支票 A,然後在處理支票 A 後再次查看是否有足夠的資金來處理支票 B。但是,如果同時處理兩張支票,系統可能會為這兩個過程讀取相同的賬戶餘額值並給出錯誤的賬戶餘額值,從而導致賬戶透支。
- 檢查然後行動。當兩個進程檢查一個值時,就會發生這種競爭情況,每個進程都將在該值上執行一個外部操作。進程都檢查該值,但只有一個進程可以獲取該值。稍後發生的過程會將值讀取為空。這會導致潛在的過時或不可用的觀察結果被用於確定程式下一步將做什麼。例如,如果一個地圖應用程式同時運行兩個需要相同位置數據的進程,則一個將首先獲取該值,而另一個不能使用它。後面的進程將數據讀取為空。
競爭條件會導致哪些安全漏洞?
如果要求程式同時執行兩個或多個操作,則設計用於按特定順序處理任務的程式可能會遇到安全問題。威脅參與者可以利用服務啟動和安全控制生效之間的時間間隔來製造死鎖或線程阻塞情況。
死鎖漏洞是一種嚴重的拒絕服務漏洞。當兩個或多個線程必須彼此等待以獲取或釋放循環鏈中的鎖時,就會發生這種情況。這種情況會導致死鎖,整個軟件系統都會停止,因為如果鍊是循環的,則永遠無法獲取或釋放此類鎖。
線程塊也會顯著影響應用程式性能。在這種類型的並發缺陷中,一個線程調用一個長時間運行的操作,同時持有一個鎖並阻止其他線程的進程。
如何識別競爭條件
檢測和識別競爭條件被認為是困難的。它們是一個語義問題,可能由代碼中的許多可能缺陷引起。最好從一開始就以防止這些問題的方式設計代碼。
程式員使用動態和靜態分析工具來識別競爭條件。靜態測試工具掃描程式而不運行它。然而,他們製造了許多虛假報告。動態分析工具的錯誤報告較少,但它們可能無法捕獲未在程式中直接執行的競爭條件。
競爭條件有時是由數據競爭產生的,當兩個線程同時針對相同的內存位置並且至少一個是寫操作時會發生這種情況。數據競爭比競爭條件更容易檢測,因為它們需要特定的條件才能發生。Go Project 的 Data Race Detector 等工具可以監控數據競爭情況。競爭條件與應用程式語義更緊密相關,並帶來更廣泛的問題。
你如何防止競爭條件?
程式員可以在操作系統和其他軟件中防止競爭條件的兩種方法包括:
- 避免共享狀態。這意味著審查代碼以確保當共享資源成為系統或進程的一部分時,原子操作已經到位,獨立於其他進程運行,並且鎖定用於強制代碼關鍵部分的原子操作。也可以使用一旦創建就無法更改的不可變對象。
- 使用線程 同步。在這裡,程式的給定部分一次只能執行一個線程。
也可以使用其他類型的技術來防止競爭條件:
存儲和內存
內存或存儲訪問的序列化也將防止競爭條件。這意味著如果讀命令和寫命令是緊挨著接收的,默認情況下讀命令首先被執行和完成。
聯網
在網絡中,如果兩個用戶試圖同時訪問一個頻道,並且在系統授予訪問權限之前,兩台計算機都沒有收到該頻道被佔用的通知,則可能會出現競爭條件。據統計,這種情況多發生在滯後時間較長的網絡中,例如使用地球同步衛星的網絡中。
為了防止這種競爭條件,必須設計一個優先級方案來給予一個用戶獨占訪問權。例如,當兩個訂戶在規定的時間增量內嘗試訪問系統時,其用戶名或號碼以字母表中較早的字母或較低的數字開頭的訂戶可能會獲得優先權。
外賣
競爭條件以多種方式出現在軟件、存儲、內存和網絡中。主動監控和預防它們是軟件和技術設計和開發的關鍵部分。
防止競爭條件尤為重要,因為黑客可以利用競爭條件漏洞來獲得對網絡的未經授權的訪問。基於競爭條件的漏洞利用的一個顯著示例稱為Dirty Cow,它利用 Linux 內核內存子系統中的缺陷來創建競爭條件,攻擊者在該條件下獲得只讀內存映射的寫入權限。