|
網(wǎng)絡(luò)技術(shù)是從1990年代中期發(fā)展起來的新技術(shù),它把互聯(lián)網(wǎng)上分散的資源融為有機(jī)整體,實(shí)現(xiàn)資源的全面共享和有機(jī)協(xié)作,使人們能夠透明地使用資源的整體能力并按需獲取信息。資源包括高性能計(jì)算機(jī)、存儲資源、數(shù)據(jù)資源、信息資源、知識資源、專家資源、大型數(shù)據(jù)庫、網(wǎng)絡(luò)、傳感器等。 當(dāng)前的互聯(lián)網(wǎng)只限于信息共享,網(wǎng)絡(luò)則被認(rèn)為是互聯(lián)網(wǎng)發(fā)展的第三階段。 了解什么是競爭條件,以及它們?yōu)槭裁磿?huì)引發(fā)安全問題。本文向您展示了如何在類 UNIX® (Unix-like)系統(tǒng)中處理常見的競爭條件,包括如何正確地創(chuàng)建鎖文件、鎖文件的替代者,如何處理文件系統(tǒng),以及如何處理共享目錄(特別是如何在 /tmp 目錄下正確創(chuàng)建臨時(shí)目錄)。需要您對信號處理稍有了解。 通過一個(gè)偷竊而來的口令,Mallory 成功地登錄到一臺運(yùn)行 Linux 的重要服務(wù)器。其帳號是一個(gè)非常受限的帳號,但是 Mallory 知道如何使用它來制造麻煩。Mallory 安裝并運(yùn)行了一個(gè)行為非常奇怪的小程序,該程序使用多個(gè)進(jìn)程在 /tmp 目錄下快速地創(chuàng)建和刪除很多不同的符號鏈接文件。(符號鏈接文件也稱為 symlink,是一種簡單的文件,當(dāng)被訪問時(shí),它會(huì)將請求重定向到另一個(gè)文件。)Mallory 的程序不停地創(chuàng)建和刪除很多指向同一特殊文件(/etc/passwd,口令文件)的不同符號鏈接文件。 這臺重要的服務(wù)器的安全措施之一是,它每天都運(yùn)行 Tripwire —— 具體地說,是較老的 2.3.0 版本。Tripwire 是一個(gè)檢測重要文件是否被篡改的安全程序。與很多程序一樣,Tripwire 啟動(dòng)時(shí)會(huì)嘗試著創(chuàng)建一個(gè)臨時(shí)文件。Tripwire 會(huì)查看并斷定不存在名為“/tmp/twtempa19212”的文件,所以看起來這是一個(gè)合適的臨時(shí)文件名稱。但是在 Tripwire 完成檢查后,Mallory 的程序就會(huì)使用該名稱創(chuàng)建一個(gè)符號鏈接文件。這不是偶然的;Mallory 程序的設(shè)計(jì)目標(biāo)就是創(chuàng)建最有可能為 Tripwire 所使用的文件名。然后 Tripwire 就會(huì)打開該文件,開始寫入臨時(shí)信息,但不用創(chuàng)建新的空文件,Tripwire 現(xiàn)在正在重寫口令文件!從那時(shí)起,任何人 —— 甚至是管理員 —— 都不能登錄到該系統(tǒng),因?yàn)榭诹钗募呀?jīng)被破壞了。更糟的是,Mallory 的攻擊完全可以覆蓋所有文件,包括服務(wù)器上存儲的重要數(shù)據(jù)。 競爭條件簡介 這是個(gè)假想的故事;“Mallory”是攻擊者的一個(gè)慣用名。但是這類攻擊,以及它所利用的缺陷,都極其常見。問題是很多程序都容易受到名為“競爭條件”的安全問題的影響。 當(dāng)由于事件次序異常而造成對同一資源的競爭,從而導(dǎo)致程序無法正常運(yùn)行時(shí),就會(huì)出現(xiàn)“競爭條件”。注意,競爭條件無需介入同一程序的兩個(gè)部分之間的競爭;如果一個(gè)外部的攻擊者可以通過意想不到的方式干擾程序,那么就會(huì)出現(xiàn)很多安全問題。例如,如果 Tripwire 2.3.0 確定某個(gè)文件不存在,它就會(huì)嘗試著創(chuàng)建該文件,而不去考慮在進(jìn)行這兩個(gè)步驟期間,該文件是否已經(jīng)被攻擊者創(chuàng)建。幾十年前,競爭條件還不是什么問題;那時(shí),計(jì)算機(jī)系統(tǒng)通常在同一時(shí)刻只能運(yùn)行一個(gè)單獨(dú)的程序,什么都不能打斷它或者與它競爭。但是,當(dāng)今的計(jì)算機(jī)通常需要同時(shí)運(yùn)行大量的進(jìn)程和線程,經(jīng)常還會(huì)有多個(gè)處理器確實(shí)在同時(shí)運(yùn)行不同的程序。這樣做更靈活,但是有一個(gè)危險(xiǎn):如果這些進(jìn)程和線程共享了所有的資源,那么它們都可能互相影響。實(shí)際上,競爭條件缺陷是軟件的更常見缺陷之一,此外,在類 Unix 系統(tǒng)上,/tmp 和 /var/tmp 目錄經(jīng)常會(huì)被錯(cuò)誤地使用,從而導(dǎo)致競爭條件。 不過,我們首先需要了解一些術(shù)語。所有 類-Unix 系統(tǒng)都支持用戶進(jìn)程;每個(gè)進(jìn)程都有自己的內(nèi)存空間(其他進(jìn)程通常無法訪問)。底層的內(nèi)核會(huì)盡量使進(jìn)程看起來像是在同時(shí)運(yùn)行;在多處理器的系統(tǒng)中,它們確實(shí)可以同時(shí)運(yùn)行。從理論上講,一個(gè)進(jìn)程可以擁有一個(gè)或多個(gè)線程;這些線程可以共享內(nèi)存。線程也可以同時(shí)運(yùn)行。由于線程可以共享內(nèi)存,所以,相對于進(jìn)程,線程之間更有可能產(chǎn)生競爭條件;正是由于這個(gè)原因,多線程程序的調(diào)試要困難得多。Linux 內(nèi)核有一個(gè)非常好的基本設(shè)計(jì):只有線程,并且一些線程可以與其他線程共享內(nèi)存(這樣實(shí)現(xiàn)了傳統(tǒng)的線程),而另外一些線程則不能(這樣就實(shí)現(xiàn)了獨(dú)立進(jìn)程)。 為了理解競爭條件,讓我們首先來看一個(gè)非常普通的 C 聲明: 清單 1. 普通的 C 聲明 b = b + 1; 看起來非常簡單,不是嗎?但是,讓我們假定有兩個(gè)線程在運(yùn)行這一行代碼,在這里,“b”是一個(gè)由兩個(gè)線程共享的變量,“b”的初始值為“5”。以下是一個(gè)似是而非的執(zhí)行次序: 清單 2. 使用共享的“b”的可能執(zhí)行次序 (thread1) load b into some register in thread 1. (thread2) load b into some register in thread 2. (thread1) add 1 to thread 1's register, computing 6. (thread2) add 1 to thread 2's register, computing 6. (thread1) store the register value (6) to b. (thread2) store the register value (6) to b. 初始值為 5,然后兩個(gè)線程分別加 1,但是最終的結(jié)果是 6... 而不是應(yīng)該得到的 7。問題在于,兩個(gè)線程互相干擾,從而導(dǎo)致產(chǎn)生錯(cuò)誤的最終答案。 通常,線程不是以原子的方式執(zhí)行的;另一個(gè)線程可以在任何兩個(gè)指令期間打斷它,而且還可以使用一些共享的資源。如果一個(gè)安全程序的線程沒有預(yù)防這些中斷,那么另一個(gè)線程就可以干擾該安全程序的線程。在安全程序中,不管在任何一對指令中間運(yùn)行了多少其他線程的代碼,程序都必須正確地運(yùn)行。關(guān)鍵是,當(dāng)您的程序訪問任意資源時(shí),要確定其他某個(gè)線程是否可能因?yàn)槭褂迷撡Y源對您的程序造成干擾。 解決競爭條件 競爭條件的典型解決方案是,確保程序在使用某個(gè)資源(比如文件、設(shè)備、對象或者變量)時(shí),擁有自己的專有權(quán)。獲得某個(gè)資源的專有權(quán)的過程稱為加鎖。鎖不太容易處理。死鎖(“抱死,deadly embrace”)是常見的問題,在這種情形下,程序會(huì)因等待對方釋放被加鎖的資源而無法繼續(xù)運(yùn)行。要求所有線程都必須按照相同的順序(比如,按字母排序,或者從“l(fā)argest grain”到“smallest grain”的順序)獲得鎖,這樣可以避免大部分死鎖。另一個(gè)常見問題是活鎖(livelock),在這種情況下,程序至少成功地獲得和釋放了一個(gè)鎖,但是以這種方式無法將程序再繼續(xù)運(yùn)行下去。如果一個(gè)鎖被掛起,順利地釋放它會(huì)很難。簡言之,編譯在任何情況下都可以按需要正確地加鎖和釋放的程序通常很困難。 有時(shí),可以一次執(zhí)行一個(gè)單獨(dú)操作來完成一些特殊的操作,從而使您不需要顯式地對某個(gè)資源進(jìn)行加鎖而后再解鎖。這類操作稱為“原子”操作,只要能夠使用這類操作,它們通常是最好的解決方案。 有一些錯(cuò)誤是如此常見,所以,為了避免犯這些錯(cuò)誤,您需要了解它們。一個(gè)問題是,以不總是鎖定某資源的方式創(chuàng)建鎖文件;您應(yīng)該學(xué)習(xí)如何正確創(chuàng)建它們,或者轉(zhuǎn)而采取不同的加鎖機(jī)制。您還需要正確地處理文件系統(tǒng)中的競爭,其中包括如何處理永遠(yuǎn)危險(xiǎn)的共享目錄 /tmp 和 /var/tmp,以及如何安全地使用信號。下一章中將描述如何安全使用它們。 網(wǎng)絡(luò)的神奇作用吸引著越來越多的用戶加入其中,正因如此,網(wǎng)絡(luò)的承受能力也面臨著越來越嚴(yán)峻的考驗(yàn)―從硬件上、軟件上、所用標(biāo)準(zhǔn)上......,各項(xiàng)技術(shù)都需要適時(shí)應(yīng)勢,對應(yīng)發(fā)展,這正是網(wǎng)絡(luò)迅速走向進(jìn)步的催化劑。 |
溫馨提示:喜歡本站的話,請收藏一下本站!