国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于錯誤路徑行為一致性的內(nèi)核引用計數(shù)缺陷檢測

2023-07-20 11:21
計算機(jī)研究與發(fā)展 2023年7期
關(guān)鍵詞:內(nèi)核代碼計數(shù)

熊 忻 談 心 張 源

(復(fù)旦大學(xué)計算機(jī)科學(xué)技術(shù)學(xué)院 上海 200438)

引用計數(shù)(reference counting,refcount)技術(shù)是現(xiàn)代編程語言中一種常見的內(nèi)存對象管理技術(shù).例如,Lisp,Python,Ruby 等語言的垃圾回收算法的實現(xiàn)即基于引用計數(shù)技術(shù).與這些編程語言相比,C 語言沒有自帶的垃圾回收機(jī)制.因此,許多用C 語言開發(fā)的重要開源軟件,如Linux 內(nèi)核、FreeBSD 內(nèi)核等,往往需要自己實現(xiàn)引用計數(shù)機(jī)制來管理內(nèi)存對象.然而,由于軟件代碼日益復(fù)雜,程序開發(fā)者時常會對引用計數(shù)進(jìn)行錯誤的操作,引發(fā)引用計數(shù)缺陷,進(jìn)而造成內(nèi)存泄露、釋放后使用等內(nèi)存安全問題.這些內(nèi)存安全問題會進(jìn)一步被利用于執(zhí)行本地提權(quán)攻擊、DoS攻擊等,嚴(yán)重危害內(nèi)核系統(tǒng)的正常運行[1-2].近年來,由引用計數(shù)導(dǎo)致的安全漏洞層出不窮(例如CVE-2022-28356[3],CVE-2021-20226[4],CVE-2022-29581[5]等),對引用計數(shù)缺陷進(jìn)行檢測也成為構(gòu)建可信內(nèi)核的重要手段.

由于引用計數(shù)機(jī)制的重要性,近年來許多研究者都在探索針對引用計數(shù)缺陷的檢測方案.火狐開發(fā)者基于動態(tài)測試的方法,采用引用計數(shù)動態(tài)追蹤與平衡技術(shù)[6]來檢測運行時發(fā)生的引用計數(shù)問題.同時,由于動態(tài)測試方法覆蓋代碼有限,大部分的研究工作[7-11]通過基于源代碼的靜態(tài)程序分析技術(shù)來檢測普通用戶態(tài)程序[7-9]和操作系統(tǒng)內(nèi)核[10-11]中的引用計數(shù)缺陷.其中,針對Linux 內(nèi)核,工具CID[10]基于其對內(nèi)核中引用計數(shù)行為特征的觀察,提出了二維不一致性檢測方案;LinKRID[11]采用符號執(zhí)行的方法,借助局部作用域中引用計數(shù)變化與全局引用變化的數(shù)量的關(guān)系檢測缺陷.然而文獻(xiàn)[10-11]所述的2 個工作的檢測方法均存在一定的局限性,無法覆蓋內(nèi)核中所有引用計數(shù)缺陷的模式,存在一定的漏報.具體而言,CID 無法分析使用函數(shù)較少的引用對象;LinKRID 不關(guān)注內(nèi)部引用對象的行為正確性.總之,由于Linux 內(nèi)核代碼的復(fù)雜性,當(dāng)前研究者還在探索針對Linux 內(nèi)核中引用計數(shù)缺陷檢測的各種不同思路和方案,目前尚沒有一個完備的檢測方案.

與此同時,在內(nèi)核缺陷檢測方面,近年來國內(nèi)外的許多安全研究者都關(guān)注錯誤處理行為在缺陷檢測當(dāng)中的作用.具體來說,當(dāng)內(nèi)核的功能出現(xiàn)錯誤時,需要執(zhí)行包括狀態(tài)回滾等行為在內(nèi)的諸多特定操作.因此,發(fā)生錯誤之后的代碼路徑(稱為錯誤處理路徑)本身含有特殊的程序語義,并可為檢測各類漏洞提供豐富的語義信息.Hector[12]發(fā)現(xiàn)鄰近的故障處理塊通常需要做出相似的資源釋放行為,其檢測一類由于故障處理代碼中資源釋放行為缺失而造成的缺陷.APEx[13]則提出了一個識別故障處理代碼的方案,并進(jìn)一步對錯誤檢查缺失缺陷進(jìn)行檢測.越來越多的研究者認(rèn)識到錯誤路徑特征可以幫助檢測多類內(nèi)核缺陷[14-16],并取得了顯著成果.但是,尚未有工作討論錯誤路徑對于內(nèi)核引用計數(shù)缺陷檢測的幫助.

本文探討了如何利用錯誤處理路徑提供的語義信息來進(jìn)行引用計數(shù)缺陷檢測,提出了基于錯誤路徑行為一致性分析的引用計數(shù)缺陷檢測方案.該檢測方案主要基于以下觀察:盡管功能不同的函數(shù)采取的錯誤處理行為不同,相應(yīng)的引用計數(shù)操作也不同.但是,對于一個函數(shù)內(nèi)部而言,所有的錯誤路徑對同一個被計數(shù)對象往往都維持類似的引用計數(shù)操作和行為.這是因為,如果一個函數(shù)中不同的錯誤路徑造成了不同的引用變化,那么該函數(shù)的調(diào)用者會因此產(chǎn)生困擾.這意味著該函數(shù)的調(diào)用者需要準(zhǔn)確判斷該函數(shù)內(nèi)部產(chǎn)生的錯誤情況,并根據(jù)不同的情況進(jìn)行相應(yīng)的引用計數(shù)操作,以確保該函數(shù)失敗時最終的對象引用計數(shù)是正確的.這會給函數(shù)調(diào)用者帶來額外的開發(fā)負(fù)擔(dān),并且極易導(dǎo)致更多的代碼缺陷.因此,在內(nèi)核中同一個函數(shù)中的不同錯誤路徑應(yīng)對同一個對象的引用計數(shù)有相似的故障處理行為.這樣可以保證函數(shù)發(fā)生錯誤退出時,各路徑上的引用計數(shù)的狀態(tài)是一致的,以便函數(shù)的調(diào)用者可以對所有錯誤路徑做統(tǒng)一的引用計數(shù)處理.

基于上述觀察,本文提出了一種基于錯誤路徑行為一致性分析的檢測方案.同一個函數(shù)內(nèi),錯誤路徑上的引用計數(shù)行為應(yīng)趨于一致;當(dāng)大部分路徑行為一致而少部分路徑行為異常時,則認(rèn)為這些異常路徑上存在引用計數(shù)缺陷.具體來說,本方案根據(jù)路徑上的行為將錯誤路徑劃分為進(jìn)行引用處理和不進(jìn)行引用處理2 種情況.其中,對引用進(jìn)行處理主要包含引用計數(shù)減操作和引用對象逃逸操作2 類具體的代碼行為.具體來說,對于一個函數(shù),本方案首先識別各條錯誤處理路徑上是否存在引用計數(shù)減和引用逃逸2 類處理行為,將路徑對應(yīng)地劃分為存在處理行為和不存在處理行為2 類.隨后統(tǒng)計存在處理行為和不存在處理行為的路徑數(shù)量比例,并依此評估錯誤路徑上引用計數(shù)相關(guān)行為的一致性程度.當(dāng)一個函數(shù)中的絕大部分錯誤路徑行為分類一致,僅有少部分路徑異常時,則推斷少數(shù)路徑的行為存在問題,即存在引用計數(shù)缺陷.與已有工作相比,本檢測方案引入了錯誤路徑的語義來推斷函數(shù)應(yīng)該采取正確的引用計數(shù)行為,只需要引用計數(shù)對象被錯誤路徑操作即可進(jìn)行檢測,其適用限制與已有方案[10-11]不同.因此可以覆蓋到已有工作檢測不到的缺陷,并與已有工作形成檢測能力的互補(bǔ).

基于上述檢測方案,本文實現(xiàn)了一個針對Linux 內(nèi)核的引用計數(shù)缺陷檢測系統(tǒng).該系統(tǒng)以內(nèi)核源代碼編譯而成的LLVM(low level virtual machine)的中間表示(intermediate representation,IR)為輸入,經(jīng)過預(yù)處理、行為分析和缺陷檢測3 個步驟,最終輸出缺陷報告.本系統(tǒng)在Linux 內(nèi)核版本5.6-rc2 和版本5.17 上分別有17 個和7 個缺陷已經(jīng)得到了開發(fā)者的確認(rèn).此外,在與CID 的對比實驗中,本方案在內(nèi)核版本5.6-rc2上發(fā)現(xiàn)了已有工作無法發(fā)現(xiàn)的9 個引用計數(shù)缺陷.該結(jié)果說明本文提出的新方案是有效且具有實際意義的,并且與已有工作形成檢測能力的互補(bǔ).

簡而言之,本文的主要貢獻(xiàn)包括3 個方面:

1)將錯誤路徑信息引入引用計數(shù)缺陷檢測中,提出了一種基于錯誤路徑行為一致性分析的檢測方案.該方案通過對同一個函數(shù)中的不同錯誤路徑上的引用計數(shù)行為進(jìn)行一致性分析以檢測缺陷.

2)基于1)中的檢測方案,實現(xiàn)了一個引用計數(shù)缺陷檢測系統(tǒng).該系統(tǒng)對錯誤路徑和引用計數(shù)操作分別進(jìn)行了自動識別與收集,分析各錯誤路徑上的引用計數(shù)行為,最終通過一致性分析識別其中違背了函數(shù)主流傾向的行為,將其作為潛在的缺陷進(jìn)行報告.

3)將檢測系統(tǒng)應(yīng)用于開源內(nèi)核Linux,發(fā)現(xiàn)了Linux內(nèi)核中真實存在的缺陷.工具在內(nèi)核版本 5.6-rc2 和版本5.17 上分別報告了66 個和46 個潛在缺陷,經(jīng)過人工驗證,分別有21 個和9 個報告被確認(rèn)為真實的引用計數(shù)缺陷.

1 相關(guān)工作

1.1 引用計數(shù)缺陷檢測

基于不同的假設(shè),研究者們提出多種檢測內(nèi)核中的引用計數(shù)缺陷的方式.這些檢測方案通常的步驟為:首先,觀察引用計數(shù)缺陷特征或引用計數(shù)行為通用模式;然后,根據(jù)特征進(jìn)行建模;最后,篩選出不符合模型的情況作為潛在缺陷.

火狐開發(fā)者與測試者嘗試使用動態(tài)測試的方法,采用引用計數(shù)追蹤與平衡技術(shù)[6],對引用計數(shù)進(jìn)行追蹤與平衡.但由于動態(tài)測試極大受制于輸入,更多研究采用了靜態(tài)分析以及符號執(zhí)行的方法來檢測引用計數(shù)缺陷.Referee[7]提出了一種利用符號模型檢測的方法,但該方法僅針對全部控制流已知的封閉程序.Pungi[8]基于函數(shù)中引用計數(shù)變化與引用對象逃逸數(shù)量相等的假設(shè),對Python/C 程序進(jìn)行了引用計數(shù)缺陷的檢測.但這種方案需要非常精確的函數(shù)間逃逸分析,在操作系統(tǒng)內(nèi)核中難以實際應(yīng)用.RID[9]通過比較函數(shù)參數(shù)與返回值,對函數(shù)外無法區(qū)分的路徑上的引用計數(shù)行為進(jìn)行不一致性檢測.但由于其假設(shè)相對嚴(yán)格,這種方法能檢測到的范圍比較小.CID[10]基于引用計數(shù)增加行為與引用計數(shù)減少行為之間存在嚴(yán)格關(guān)聯(lián),以及引用計數(shù)增加行為和引用計數(shù)減少行為所使用的函數(shù)在不同的使用情境下行為具有相同傾向性的假設(shè),提出了針對Linux 內(nèi)核的二維一致性檢測方案.但該方法依舊無法覆蓋內(nèi)核中的所有代碼,當(dāng)分析的引用計數(shù)對象被使用的函數(shù)較少時,該方案效果較差.LinKRID[11]同樣針對Linux 內(nèi)核,其采用符號執(zhí)行的方法,通過判斷局部作用域中引用計數(shù)變化與全局引用變化是否相同來檢測缺陷.但在檢測時,LinKRID 直接排除了內(nèi)部引用對象,因此它也無法覆蓋所有代碼.同樣針對Linux 內(nèi)核,本文提出了一種不同的檢測方案,該方案主要依賴于對錯誤路徑信息的分析.因此,本文工作并不具有上述的限制,可以覆蓋部分已有工作[10-11]覆蓋不到的代碼,與其形成檢測能力的互補(bǔ).

1.2 利用錯誤路徑進(jìn)行缺陷檢測

部分研究者觀察到錯誤路徑的語義能夠被用來推斷路徑相關(guān)的代碼行為,尤其是安全相關(guān)行為.進(jìn)一步地,研究者發(fā)現(xiàn)這些與錯誤路徑相關(guān)的語義可被利用以進(jìn)行缺陷檢測.Hector[12]主要研究了錯誤處理代碼和資源釋放行為之間的關(guān)系,其認(rèn)為當(dāng)一個故障處理塊需要進(jìn)行資源釋放時,其附近的故障處理塊通常需要做同樣的資源釋放行為.研究者們還基于該假設(shè)對由于故障處理代碼中資源釋放行為缺失而造成的缺陷進(jìn)行了檢測.APEx[13]則關(guān)注于API 調(diào)用相關(guān)的錯誤處理代碼.首先,對于每一個API,APEx會收集不同返回值上的約束情況,并推斷完整的錯誤處理行為.其次,APEx 檢測該API 所有的調(diào)用點,檢查每一個調(diào)用點是否都執(zhí)行了完整的錯誤處理行為,從而識別錯誤處理缺失缺陷.ErrDoc[14]將故障處理行為相關(guān)的缺陷分為4 種表現(xiàn)形式,并基于這4 種形式構(gòu)建了檢測工具.CHEQ[15]提出了錯誤處理路徑與安全檢查之間的關(guān)系,通過安全檢查識別錯誤處理代碼,進(jìn)而識別錯誤處理缺失等缺陷.

目前尚未有工作通過錯誤處理路徑信息來檢測引用計數(shù)缺陷.與已有工作關(guān)注的錯誤處理缺失、內(nèi)存釋放缺失缺陷相比,引用計數(shù)缺陷的成因和特征更復(fù)雜,因此已有工作的技術(shù)和方案并不能直接應(yīng)用于引用計數(shù)缺陷檢測場景.本文工作將錯誤路徑信息引入引用計數(shù)缺陷檢測,并實現(xiàn)了可行的檢測方案.

2 本文檢測方案

2.1 錯誤路徑上的引用相關(guān)行為一致性

Linux 內(nèi)核中的函數(shù)往往具有非常復(fù)雜的邏輯.并且在函數(shù)執(zhí)行時,只有當(dāng)內(nèi)核狀態(tài)(如全局標(biāo)志位,全局對象等)滿足特定條件,功能才能正常執(zhí)行;反之,則會觸發(fā)故障錯誤處理邏輯,根據(jù)情況進(jìn)行中斷執(zhí)行、嘗試修復(fù)故障或恢復(fù)執(zhí)行等不同的處理.在一個函數(shù)中,發(fā)現(xiàn)函數(shù)執(zhí)行錯誤并對錯誤故障進(jìn)行處理的路徑被稱為錯誤路徑.

對于錯誤路徑上引用計數(shù)對象及其相應(yīng)行為,本文有2 點觀察:

1)當(dāng)一個函數(shù)發(fā)生錯誤時,其錯誤故障處理發(fā)生的位置具有一致性.具體來說,當(dāng)某個函數(shù)在執(zhí)行過程中遭遇錯誤故障后,相對應(yīng)的故障處理行為可以在該函數(shù)內(nèi)進(jìn)行,也可以由它們的調(diào)用函數(shù)依據(jù)該函數(shù)的返回值在外部進(jìn)行相應(yīng)處理.但是,對于同一個函數(shù)的不同錯誤路徑,其處理錯誤故障的位置基本相同.也就是說,即使一個函數(shù)觸發(fā)了不同的錯誤路徑,這些路徑要么均在該函數(shù)內(nèi)進(jìn)行相應(yīng)的故障處理,要么均不在函數(shù)內(nèi)進(jìn)行任何故障處理,而是留給調(diào)用者統(tǒng)一處理,即一個函數(shù)錯誤故障處理發(fā)生的位置具有一致性.從開發(fā)者的編程習(xí)慣來說,該性質(zhì)也較為合理.因為,若一個函數(shù)內(nèi)部的錯誤路徑部分進(jìn)行了故障處理,而另一部分沒有進(jìn)行,那么,該函數(shù)的所有調(diào)用者均需要了解函數(shù)內(nèi)部的實現(xiàn),在函數(shù)外部精心地區(qū)分內(nèi)部執(zhí)行的路徑,并有針對性地進(jìn)行相應(yīng)的錯誤故障處理,這極大地增加了函數(shù)調(diào)用者的負(fù)擔(dān),且提高了編程錯誤出現(xiàn)的可能性.

2)基于1)中性質(zhì),在同一個函數(shù)內(nèi)的各錯誤路徑上執(zhí)行的引用相關(guān)行為具有一致性,即要么各路徑都執(zhí)行引用相關(guān)行為對錯誤故障進(jìn)行處理,要么均不進(jìn)行任何處理.錯誤路徑上與引用相關(guān)的行為主要有2 種:引用計數(shù)的減操作和引用逃逸.對大部分內(nèi)核業(yè)務(wù)函數(shù)而言,其正常的業(yè)務(wù)邏輯是先獲得一些重要對象的引用(伴隨引用計數(shù)的增操作),然后再使用該對象進(jìn)行一些業(yè)務(wù)處理.如果在后續(xù)處理過程中遭遇錯誤故障,則要進(jìn)行相應(yīng)的故障處理.如果錯誤路徑上要執(zhí)行類似“回滾”的故障處理行為,則通常會進(jìn)行引用計數(shù)減操作以平衡之前的引用計數(shù)加操作,使對象的引用計數(shù)數(shù)值回滾到進(jìn)入該函數(shù)之前的初態(tài);如果錯誤路徑要進(jìn)行中斷操作并退出,一般該對象會存在引用逃逸,以方便外部代碼通過對逃逸的引用使用該對象進(jìn)行后續(xù)操作.

2.2 基于一致性分析的缺陷檢測方案

基于2.1 節(jié)中的2 點觀察,本文提出基于錯誤路徑引用相關(guān)行為的一致性分析來檢測引用計數(shù)缺陷的方案.該方案的原理如圖1 所示.對于目標(biāo)函數(shù),首先,確定其中存在引用計數(shù)增的主要對象,稱之為被計數(shù)對象.其次,將函數(shù)中的路徑分為正常路徑和錯誤路徑2 類.本方案的檢測對象主要是錯誤路徑.對于每條錯誤路徑,定位錯誤路徑上被計數(shù)對象的引用計數(shù)行為和引用逃逸行為.然后,依據(jù)各路徑上的具體行為,將各路徑劃分為2 類:一類是存在引用相關(guān)行為的路徑,即存在引用計數(shù)減操作和引用逃逸;另一類是不存在引用相關(guān)行為(即不處理引用)的路徑,也就是既不存在引用計數(shù)減操作,也不存在引用逃逸.劃分完成后,確定數(shù)量較多的一類所具有的特征為主流行為,另一類數(shù)量較少的為異常行為.正常來說,無缺陷的函數(shù)所有的錯誤路徑應(yīng)該都會屬于同一個類別,即同時屬于存在引用相關(guān)行為或同時屬于不存在引用相關(guān)行為,而不會存在異常行為類.一旦存在異常行為類,這些類所包含的路徑都與主流類存在不一致,有可能包含缺陷,即本方案檢測出的引用計數(shù)缺陷.

Fig.1 Illustration of our proposed refcount bug detection scheme圖1 本文引用計數(shù)缺陷檢測方案示意圖

以函數(shù)siw_fastreg_mr為例,其源代碼如圖2 所示.函數(shù)在第5 行框中通過調(diào)用函數(shù)siw_mem_id2obj進(jìn)行了對象mem的引用計數(shù)增加行為,mem為該函數(shù)的被計數(shù)對象.在第8~35 行進(jìn)行了一系列操作,最后在第37 行框進(jìn)行引用計數(shù)減少行為,并在第38行返回記錄狀態(tài)的變量rv.函數(shù)在第10~28 行之間對某些內(nèi)核狀態(tài)和執(zhí)行中間情況進(jìn)行了安全檢查.安全檢查失敗即意味著函數(shù)執(zhí)行遭遇錯誤,此時需要進(jìn)行故障處理.具體來說,第11,15,20,25 行相關(guān)的代碼塊均在執(zhí)行故障處理,涉及的路徑均為錯誤路徑,具體的路徑分析情況如表1 所示.

Table 1 Paths in Function siw_fastreg_mr表1 函數(shù)siw_fastreg_mr 中的路徑

Fig.2 Code of function siw_fastreg_mr圖2 函數(shù) siw_fastreg_mr 代碼

路徑①~④都屬于錯誤路徑.進(jìn)一步分析這些路徑上的引用相關(guān)行為可以看到,路徑②~④上最終都會跳轉(zhuǎn)到函數(shù)尾部進(jìn)行引用計數(shù)減的操作.只有路徑①在第12 行沒有進(jìn)行引用計數(shù)操作的情況下退出當(dāng)前函數(shù),且也不存在引用逃逸的情況.顯然,路徑②~④會被劃分為存在引用相關(guān)行為,即該函數(shù)的主流情況;而路徑①是函數(shù)中的異常情況,極有可能存在引用計數(shù)缺陷.

3 系統(tǒng)設(shè)計

基于第2 節(jié)所述的檢測方案,本文設(shè)計并實現(xiàn)了一套針對內(nèi)核引用計數(shù)缺陷的檢測系統(tǒng).本節(jié)首先介紹該系統(tǒng)的架構(gòu),然后逐一介紹系統(tǒng)的各主要模塊.

3.1 本文系統(tǒng)架構(gòu)

本文流程圖如圖3 所示.本系統(tǒng)以內(nèi)核源代碼以及由源碼編譯而成的LLVM IR[17]文件作為輸入.

Fig.3 Workflow of our proposed detecting system圖3 本文檢測系統(tǒng)流程圖

分析工具主要基于LLVM IR 進(jìn)行靜態(tài)程序分析,以源代碼文件作為輔助信息,總共經(jīng)過預(yù)處理、行為分析、缺陷檢測3 個步驟進(jìn)行處理,最終產(chǎn)出潛在缺陷的分析報告.

1)預(yù)處理.在預(yù)處理階段,系統(tǒng)主要對輸入的IR進(jìn)行基礎(chǔ)的靜態(tài)分析,包括內(nèi)核調(diào)用圖構(gòu)建、函數(shù)內(nèi)控制流分析和函數(shù)內(nèi)指針分析,為后續(xù)的分析步驟提供控制流和數(shù)據(jù)流信息支持.

2)行為分析.在行為分析階段,系統(tǒng)對目標(biāo)函數(shù)內(nèi)各條錯誤路徑上的引用計數(shù)行為進(jìn)行采集和分析,并傳遞給后續(xù)缺陷檢測階段.具體來說,系統(tǒng)首先在內(nèi)核中識別出所有符合引用計數(shù)域特征的結(jié)構(gòu)域,即識別內(nèi)核結(jié)構(gòu)體中的引用計數(shù)字段,并定位所有操作這些字段的代碼行為.其次,對于涉及引用計數(shù)操作的函數(shù),系統(tǒng)開展錯誤路徑識別,收集函數(shù)中所有的錯誤路徑,并標(biāo)記路徑上的引用計數(shù)操作.最后,進(jìn)行逃逸行為分析,標(biāo)記各錯誤路徑上的引用逃逸行為.

3)缺陷檢測.在缺陷檢測環(huán)節(jié),系統(tǒng)將包含引用計數(shù)操作的函數(shù)作為目標(biāo)函數(shù),并基于行為分析環(huán)節(jié)對目標(biāo)函數(shù)的分析結(jié)果開展行為一致性分析.具體來說,系統(tǒng)對各錯誤路徑上的具體行為進(jìn)行分類,然后計算目標(biāo)函數(shù)的行為一致性分?jǐn)?shù).若分?jǐn)?shù)高于閾值,則生成對應(yīng)的缺陷報告.此外,系統(tǒng)還迭代地對目標(biāo)函數(shù)進(jìn)行延展,以擴(kuò)大目標(biāo)函數(shù)的范圍.

3.2 預(yù)處理

預(yù)處理階段主要是進(jìn)行一些基本的靜態(tài)程序分析以獲取控制流和數(shù)據(jù)流的信息,作為后續(xù)分析和缺陷檢測的基礎(chǔ).具體來說,預(yù)處理階段主要包含調(diào)用圖構(gòu)建、函數(shù)內(nèi)控制流分析和指針分析3 部分.

本系統(tǒng)的調(diào)用圖構(gòu)建和函數(shù)內(nèi)控制流分析主要基于CID[10]使用的靜態(tài)分析框架實現(xiàn).在構(gòu)建調(diào)用圖時,對于直接函數(shù)調(diào)用,連接直接函數(shù)調(diào)用指令所在的函數(shù)和目標(biāo)函數(shù).與此同時,內(nèi)核中還存在大量的間接函數(shù)調(diào)用,本系統(tǒng)使用MLTA(multi-layer type analysis)算法[18]對間接函數(shù)調(diào)用的目的地進(jìn)行識別.對于函數(shù)內(nèi)的控制流,LLVM 框架[19]支持函數(shù)內(nèi)控制流分析.

特別地,本文發(fā)現(xiàn)目前對MLTA 算法的處理還不夠完備.例如,MLTA 僅能識別函數(shù)指針在結(jié)構(gòu)域初始化或直接賦值的情況下被提供的情況.然而,本文發(fā)現(xiàn)在內(nèi)核代碼中亦存在函數(shù)指針直接作為函數(shù)調(diào)用參數(shù)被提供的情況.因此,在現(xiàn)有MLTA 框架的基礎(chǔ)上,本文針對函數(shù)指針作為函數(shù)參數(shù)被傳遞的情況進(jìn)行建模,類似的改進(jìn)還包括為函數(shù)指針逃逸至全局變量的情況提供支持等,較為完善的建模降低了原有算法引入的誤報.

本系統(tǒng)的指針分析主要基于SVF 框架[20].SVF框架在LLVM IR 層面基于內(nèi)建的內(nèi)存模型進(jìn)行函數(shù)間指針分析,并最終生成稀疏數(shù)據(jù)流圖(sparse valueflow graph,SVFG).SVFG 以圖形式表達(dá)了豐富全面的數(shù)據(jù)流信息,在后續(xù)的分析過程中提供數(shù)據(jù)流信息的支撐.

3.3 行為分析

如2.2 節(jié)所述,本文檢測系統(tǒng)關(guān)注錯誤路徑上的引用計數(shù)操作和引用逃逸.在行為分析階段,需要對每個函數(shù)中的引用計數(shù)操作、錯誤路徑和引用逃逸逐一進(jìn)行分析.

1)引用計數(shù)分析.引用計數(shù)分析具體分為2 個部分,即引用計數(shù)字段的識別和字段上的相關(guān)操作識別.通常來說,在需要通過引用計數(shù)機(jī)制來管理的對象結(jié)構(gòu)體中均存在一個專門的引用計數(shù)字段.在Linux內(nèi)核中有2 個專門為引用計數(shù)設(shè)計的數(shù)據(jù)類型[21],即refcount_t 和kref 類型.但是,本文發(fā)現(xiàn)并非所有開發(fā)者在使用引用計數(shù)時都選擇這2 種數(shù)據(jù)類型,他們也可能使用其他的數(shù)據(jù)類型(比如atomic_t 類型)來作為引用計數(shù)字段,導(dǎo)致僅通過數(shù)據(jù)類型分析難以識別內(nèi)核中所有的引用計數(shù)字段.

因此,本文主要基于CID 提出的基于代碼行為特征的檢測方案來識別引用計數(shù)字段.具體來說,引用計數(shù)字段上的代碼行為主要有3 個特點:

①引用計數(shù)字段的生命周期中將經(jīng)歷引用計數(shù)值設(shè)定、引用計數(shù)增加和引用計數(shù)減少3 種行為.

②對于引用計數(shù)值設(shè)定行為,所有引用計數(shù)值只能被設(shè)定為0 或1,且至少有一個行為將引用計數(shù)值設(shè)定為1.

③每個引用計數(shù)字段上應(yīng)包含至少1 個引用計數(shù)增加1 和引用計數(shù)減少1 的行為.

基于這3 個特點,可以通過3 個步驟識別內(nèi)核中的引用計數(shù)字段.首先,收集所有內(nèi)核結(jié)構(gòu)體中數(shù)據(jù)類型為kref,refcount_t,atomic_t 等可用于引用計數(shù)目的的字段作為候選域,并且收集所有候選域上的代碼行為.然后,對于每一個候選字段,將字段上的代碼行為分為設(shè)定數(shù)值、增加數(shù)值、減少數(shù)值3 類.接著,基于引用計數(shù)字段上的代碼行為的3 個特點對每個候選域上的行為進(jìn)行審計,以篩選出符合特征的字段作為引用計數(shù)域.此外,在CID 的基礎(chǔ)上,本文對一些額外情況進(jìn)行了特殊建模.本文工具還優(yōu)化了部分實現(xiàn),提高了對源代碼進(jìn)行代碼行為分析的效率與準(zhǔn)確性.最后,收集被識別為引用計數(shù)字段為對象的操作作為引用計數(shù)操作.

2)錯誤路徑識別.本文主要依據(jù)路徑上的錯誤故障處理行為來識別錯誤路徑.根據(jù)文獻(xiàn)[15],故障處理行為大致可以分為4 種:①返回故障碼;②停止當(dāng)前執(zhí)行;③修復(fù)故障狀態(tài);④發(fā)送故障信息.這4種行為一般是通過調(diào)用對應(yīng)的處理函數(shù)或宏來實現(xiàn)的.

因此,本文主要通過2 種方式來識別故障處理行為:一是定位路徑上的函數(shù)返回值,通過后向數(shù)據(jù)流分析溯源返回值是否被賦值為故障碼.如圖4 所示,在第6 行,代碼判斷了第4 行該函數(shù)主要業(yè)務(wù)的返回值的狀態(tài).如果返回值為空指針,則說明函數(shù)主要業(yè)務(wù)執(zhí)行失敗,其將在第7 行返回對應(yīng)的故障碼.如果識別到了第7 行的故障碼,則可以判斷經(jīng)過第7 行代碼行的路徑一定為錯誤路徑.二是收集路徑上所有的函數(shù)調(diào)用和宏,通過白名單匹配的方式判斷分析路徑是否使用了停止當(dāng)前執(zhí)行/修復(fù)故障狀態(tài)/發(fā)送故障信息功能的函數(shù)調(diào)用或宏.如圖5 所示,該函數(shù)返回值為void,因此無法通過返回值是否為故障碼來識別錯誤路徑.但是,該函數(shù)在第6 行檢查了該函數(shù)之前的執(zhí)行結(jié)果.如果變量ret<0,說明之前的執(zhí)行遇到了錯誤,而后通過調(diào)用特定的故障信息發(fā)送函數(shù)pr_err打印故障信息.因此,如果識別出第7 行的故障信息發(fā)送函數(shù),即可判斷出經(jīng)過第7 行的路徑一定為錯誤路徑.

Fig.4 Example of returning error code圖4 返回故障碼示例

Fig.5 Example of sending error message圖5 發(fā)送故障信息示例

本系統(tǒng)的錯誤路徑識別功能主要基于CRIX[16]的框架來實現(xiàn),并進(jìn)行了一定的額外擴(kuò)展.對于故障碼,CRIX 主要支持了內(nèi)核中的一些常見故障碼,如EINVAL(參數(shù)錯誤故障碼)等.對于故障處理函數(shù),CRIX 使用了一個人工構(gòu)建的具有故障處理功能的函數(shù)名單.

對于故障碼識別,CRIX 只處理了內(nèi)核通用的故障碼,而本文工具實現(xiàn)了對模塊自定義故障碼的支持.具體來說,模塊自定義故障碼均以宏定義或枚舉類型的形式被定義.本文借助libclang[22]掃描代碼中所有的枚舉類型,記錄它們在內(nèi)核中的值映射,將它們作為故障碼候選.然后,根據(jù)候選枚舉類型的常量名來判斷其可能為故障碼的傾向程度.如果常量名包含類似error 等錯誤故障相關(guān)的詞,則枚舉類型更有可能是故障碼.由此,系統(tǒng)將生成一個映射表,映射表中包括枚舉量名稱、枚舉量值、故障碼傾向等信息.由于將源代碼編譯為IR 會丟失枚舉類型常量名,因此在IR 中分析函數(shù)的返回值以識別錯誤路徑時,除了獲取其IR 上的具體數(shù)值以外,還會從源代碼中獲取其對應(yīng)的字面量,通過查詢上述映射表來判斷該返回值是否與故障碼有關(guān).

錯誤路徑識別偽代碼如圖6 所示.錯誤路徑識別階段以函數(shù)的初始靜態(tài)分析結(jié)果(module)為輸入,輸出函數(shù)中識別出的錯誤處理基本塊和路徑,在缺陷檢測階段將利用該結(jié)果再進(jìn)行具體分析.本文工具在進(jìn)行錯誤處理枚舉類型分析后,從返回值(第7~14 行)和函數(shù)調(diào)用(第15~25 行)2 個維度分析所有的函數(shù):檢測故障處理行為,并對故障發(fā)生點進(jìn)行標(biāo)注,其中故障發(fā)生點以基本塊或基本塊之間的邊的形式存儲.特別地,在分析函數(shù)調(diào)用時本文也會嘗試分析其返回值,但分析策略更加保守以降低誤報.

Fig.6 Pseudocode of error path identification圖6 錯誤路徑識別偽代碼

3)逃逸行為分析.在一個函數(shù)內(nèi),如果在函數(shù)退出時,一個對象的引用被傳遞到了函數(shù)的外部,本文稱之為引用逃逸.本系統(tǒng)主要關(guān)注引用被傳遞給函數(shù)參數(shù)、函數(shù)返回值和全局變量3 種形式的引用逃逸.由于內(nèi)核代碼的復(fù)雜性,一個函數(shù)中引用的傳遞關(guān)系可能極為復(fù)雜,涉及到大量的中間變量.因此本系統(tǒng)主要收集函數(shù)返回值賦值、全局變量賦值、結(jié)構(gòu)體類型的函數(shù)參數(shù)賦值這3 種語句為源,開展反向數(shù)據(jù)流分析,借助SVF[20]提供的豐富數(shù)據(jù)流分析結(jié)果,判斷在錯誤路徑上是否存在引用逃逸行為.

3.4 缺陷檢測

缺陷檢測部分的偽代碼如圖7 所示.本文定義路徑由基本塊組成,基本塊由指令組成.缺陷檢測階段以潛在缺陷位點(〈函數(shù)調(diào)用指令,調(diào)用函數(shù)〉對)集合為輸入.對于每一個潛在缺陷位點,收集調(diào)用函數(shù)內(nèi)以函數(shù)調(diào)用指令所在基本塊為起點的所有路徑(第6 行).對于每一條路徑,以潛在缺陷位點為錨點,根據(jù)3.3 節(jié)中的分析方案進(jìn)行引用計數(shù)行為分析、錯誤路徑識別以及逃逸分析,并對每條路徑進(jìn)行標(biāo)注(第15~22 行).最后,評估錯誤路徑上的行為一致性(第26 行).如果分?jǐn)?shù)大于閾值,則進(jìn)行缺陷報告(第26~27 行);否則,考慮延展該函數(shù)作為目標(biāo)函數(shù)(第28~29 行),評估整個函數(shù)行為是否符合預(yù)設(shè)規(guī)則.

Fig.7 Pseudocode of bug detection圖7 缺陷檢測偽代碼

1)目標(biāo)函數(shù)收集與延展.只要一個函數(shù)中對某個在3.3 節(jié)中被標(biāo)識為引用計數(shù)的字段有引用計數(shù)增加的操作,該函數(shù)即可被作為本檢測工具的目標(biāo)函數(shù).然而此策略僅能檢測直接操作引用計數(shù)字段的函數(shù),分析范圍比較小.因此本文考慮在某些情況下,對目標(biāo)函數(shù)進(jìn)行迭代延展.具體來說,在滿足下面①~③條件的情況下,本文會將調(diào)用目標(biāo)函數(shù)的函數(shù)作為新的目標(biāo)函數(shù)進(jìn)行分析.

①目標(biāo)函數(shù)中不應(yīng)包含與引用計數(shù)增加行為相對應(yīng)的引用計數(shù)減少行為,即在目標(biāo)函數(shù)中不能出現(xiàn)引用計數(shù)平衡的情況.

②目標(biāo)函數(shù)中的引用計數(shù)對象一定會以函數(shù)參數(shù)或返回值的形式逃逸至調(diào)用函數(shù).

③目標(biāo)函數(shù)中與引用計數(shù)對象相關(guān)的數(shù)據(jù)流應(yīng)該直觀簡單,否則會使得結(jié)果不可信.

當(dāng)滿足這3 個條件時,可以對原目標(biāo)函數(shù)的調(diào)用視作是一個引用計數(shù)增加的操作,將調(diào)用函數(shù)視為新的目標(biāo)函數(shù).進(jìn)一步地,將逃逸出去的引用視為新目標(biāo)函數(shù)的分析對象,從而大大擴(kuò)增本系統(tǒng)的分析范圍.

2)行為一致性分析.對于每一個目標(biāo)函數(shù),本系統(tǒng)都會根據(jù)3.3 節(jié)所述對目標(biāo)函數(shù)進(jìn)行行為分析,然后基于分析結(jié)果進(jìn)行行為一致性分析.具體來說,系統(tǒng)會收集3.3 節(jié)中所識別出的錯誤路徑.每一條路徑會圍繞目標(biāo)函數(shù)中的被計數(shù)對象.基于3.3 節(jié)中引用計數(shù)分析和逃逸行為分析的結(jié)果,定位路徑上與被計數(shù)對象有關(guān)的引用計數(shù)減操作和引用逃逸操作.如果一條路徑上含有引用計數(shù)減操作或引用逃逸,則將該路徑標(biāo)識為含有引用行為的錯誤路徑;如果路徑上不包含這2 種操作,則該路徑被分類為不含引用行為的路徑.如果一個目標(biāo)函數(shù)中包含2 類路徑,則說明該函數(shù)的不同路徑上的行為并不一致;反之,如果一個函數(shù)中只包含同一類路徑,則說明函數(shù)的行為一致.

3)潛在缺陷識別.如果一個函數(shù)中的各條錯誤路徑上的引用行為不一致,則該函數(shù)有可能存在潛在缺陷.然而,由于靜態(tài)程序分析的結(jié)果并不一定準(zhǔn)確,對部分路徑的引用行為分析可能存在錯誤,因此,如果把所有程序分析識別出的不一致行為的函數(shù)全部作為缺陷,有可能導(dǎo)致產(chǎn)生大量的缺陷報告,并且會含有大量的誤報.為了降低誤報,本文引入一致性分?jǐn)?shù)來量化行為的一致性程度,即函數(shù)中采取主流行為的路徑比例.具體來說,通過3.3 節(jié)的行為分析,本文將一個函數(shù)中錯誤路徑上的行為劃分為存在引用行為和不存在引用行為2 類,并計算這2 類行為的比例分別為

這2 個比例中,比例更大的行為即為函數(shù)中的主流行為,對應(yīng)的比例即為主流行為占比,也就是一致性分?jǐn)?shù):

一致性分?jǐn)?shù)越高,說明一個函數(shù)內(nèi)的行為策略越一致,與主流行為背離的路徑行為越可疑,越有可能存在缺陷.因此,本文篩選出高于閾值的情況,視之為潛在缺陷位點.閾值越高,報告數(shù)量越少,需要人工核驗的成本越低,但必然會遺漏掉一些真正的缺陷;閾值越低,報告數(shù)量越多,需要大量的人工成本對結(jié)果進(jìn)行核驗,但能覆蓋一些分?jǐn)?shù)很低的缺陷.閾值可以根據(jù)實際生成的報告分?jǐn)?shù)和報告數(shù)量來進(jìn)行選擇.此外,在某些特殊情況下,確實可能出現(xiàn)不符合本文檢測策略的路徑,例如在涉及異步的函數(shù)中.因此,本文還會對通過分?jǐn)?shù)篩選出的潛在缺陷位點進(jìn)行簡單分析,以排除這類特殊情況.

4 實驗與結(jié)果分析

4.1 實驗設(shè)置

本文的實驗在Ubuntu 18.04 系統(tǒng)上進(jìn)行,所使用的LLVM 版本為12.0.0.該機(jī)器具有Intel?Xeon?Gold 6242 處理器(2.80 GHz, 32 核).本文分別編譯了版本5.6-rc2 和版本5.17 的Linux 內(nèi)核,編譯時所使用的配置為allyesconfig.編譯版本5.6-rc2 的內(nèi)核得到18 868個IR 文件作為系統(tǒng)的輸入,編譯版本5.17 的內(nèi)核則得到21 188 個IR 文件.

4.2 缺陷檢測結(jié)果

如3.4 節(jié)所述,本系統(tǒng)的缺陷檢測需要設(shè)置一個閾值,該閾值用以篩選檢測函數(shù)的一致性分?jǐn)?shù),標(biāo)注潛在的引用計數(shù)缺陷.在實驗過程中,本文發(fā)現(xiàn)錯誤路徑行為一致性分?jǐn)?shù)在不同的內(nèi)核版本上的分布存在一定差別,其累計分布圖(CDF)如圖8 和圖9 所示.在Linux 內(nèi)核版本5.6-rc2 和版本5.17 上,均有大量的報告聚集在0.7 分附近,超過60%的缺陷報告的分?jǐn)?shù)在0.6 分以上,在Linux 內(nèi)核版本5.17 上運行的結(jié)果分?jǐn)?shù)則相對分散,且相對集中于低分段.如果分?jǐn)?shù)設(shè)置過低,可能會導(dǎo)致需要檢查的缺陷報告數(shù)量過多.最終,本文選擇0.625 作為共同的分?jǐn)?shù)閾值,以盡可能覆蓋到更多缺陷報告,同時確保缺陷報告的總數(shù)在合理范圍內(nèi).在Linux 內(nèi)核版本5.6-rc2 上,工具一共識別到790 個引用計數(shù)域,報告了66 個潛在缺陷.在Linux 內(nèi)核版本5.17 上,工具一共識別到790 個引用計數(shù)域,報告了46 個潛在缺陷.

Fig.8 CDF of reported bugs’scores on Linux kernel 5.6-rc2 version圖8 Linux 內(nèi)核5.6-rc2 版本缺陷報告分?jǐn)?shù)累計分布圖

Fig.9 CDF of reported bugs’scores on Linux kernel 5.17 version圖9 Linux 內(nèi)核5.17 版本缺陷報告分?jǐn)?shù)累計分布圖

本文進(jìn)一步對所有的缺陷報告進(jìn)行了人工分析,最終結(jié)果如表2 所示.在這2 個版本上,分別確認(rèn)了21 和9 個引用計數(shù)缺陷.對于這些缺陷,本文也通過郵件向Linux 內(nèi)核開發(fā)者進(jìn)行了匯報,并提交了相應(yīng)的補(bǔ)丁.目前,在2 個版本上,開發(fā)者已經(jīng)確認(rèn)了其中的17 個和7 個,其余的缺陷尚在等待開發(fā)者的反饋.

Table 2 Results of Bug Detection表2 缺陷檢測結(jié)果

值得注意的是,在這2 個版本上工具匯報的結(jié)果存在一定的交集.一方面,對于一些工具的誤報情況,相關(guān)代碼在2 個內(nèi)核版本上同時存在;另一方面,對于工具檢測出的真實缺陷,由于Linux 的缺陷修復(fù)可能存在較長的時間延誤,即從缺陷被發(fā)現(xiàn)到對應(yīng)的補(bǔ)丁被真正應(yīng)用于新版內(nèi)核之間的時間間隔較長,本文在2 個版本上發(fā)現(xiàn)了一些相同的代碼缺陷(可能僅僅改變了行號).具體來說,在2 個版本上,被開發(fā)者確認(rèn)的17 個和7 個缺陷中,有4 個是相同的.此外,雖然新版本的開發(fā)和新代碼的引入會帶來一些新的缺陷,但是由于在老版本上有相當(dāng)數(shù)量的缺陷被匯報并修復(fù),總的來說,工具在版本5.17 的誤報率要大大高于版本5.6-rc2.

4.3 誤報原因分析

根據(jù)3.2 節(jié)的結(jié)果可以發(fā)現(xiàn),本文提出的系統(tǒng)在應(yīng)用過程中存在一定數(shù)量的誤報.本文進(jìn)一步人工分析了版本5.6-rc2 上45 個誤報的具體原因,并對誤報原因進(jìn)行了歸類.分析結(jié)果表明,誤報主要是由三大類原因?qū)е碌模?/p>

1)由于內(nèi)核代碼的復(fù)雜性,本工具使用的靜態(tài)程序分析在控制流分析和數(shù)據(jù)流分析上都存在不準(zhǔn)確的情況.控制流分析的不準(zhǔn)確會導(dǎo)致其無法準(zhǔn)確識別錯誤路徑;數(shù)據(jù)流分析的不準(zhǔn)確會導(dǎo)致對引用計數(shù)對象的引用計數(shù)行為分析錯誤.這兩者都會導(dǎo)致基于錯誤路徑行為一致性分析所分析的行為對象錯誤,進(jìn)而造成誤報,共有29 個誤報是由于該原因?qū)е碌?

2)如3.4 節(jié)所述,為了擴(kuò)大檢測的目標(biāo)函數(shù)范圍,工具在部分情況下會采用一種基于人工經(jīng)驗的策略對目標(biāo)函數(shù)進(jìn)行延展.但是,這種策略并不總是合理的.當(dāng)不恰當(dāng)?shù)貙⒁粋€函數(shù)作為目標(biāo)函數(shù)時,也會造成誤報,共有12 個誤報是由于該原因?qū)е碌?

3)本文使用的檢測策略并不一定在所有情況下都適用.在部分特殊場景下,開發(fā)者出于特殊考慮,可能會故意在同一個函數(shù)中的不同錯誤路徑上采取不同的引用計數(shù)行為,共有4 個誤報是由于該原因?qū)е碌?

總體來看,由于本文提出的新檢測策略導(dǎo)致的誤報,占總體誤報的比例較低(4/45),策略本身較為可靠.大部分誤報是由于靜態(tài)分析部分的分析不夠準(zhǔn)確導(dǎo)致的.

4.4 已有工作比較

為了研究本文提出的基于錯誤路徑信息的檢測方案對引用計數(shù)缺陷的檢測能力以及與已有方案的檢測能力之間的關(guān)系,本文將3.2 節(jié)中的檢測結(jié)果與CID[10]進(jìn)行了比較.CID 是近幾年比較有價值的引用計數(shù)缺陷檢測方案之一,且同樣也在Linux 內(nèi)核版本5.6-rc2 上進(jìn)行了缺陷檢測.CID 在Linux 內(nèi)核版本5.6-rc2 上共檢測到792 個引用計數(shù)域,報告了149 個引用計數(shù)缺陷,其中有44 個得到人工確認(rèn).本文的實驗結(jié)果在Linux 內(nèi)核版本5.6-rc2 上識別出790 個引用計數(shù)域,總共報告了66 個引用計數(shù)缺陷,其中21 個得到人工確認(rèn).

本文進(jìn)一步比較了CID 和本文所發(fā)現(xiàn)的引用計數(shù)缺陷,結(jié)果如圖10 所示.兩者發(fā)現(xiàn)的缺陷交集有12 個;有9 個缺陷只有本文工具能檢測到,而CID 無法檢測到;有32 個缺陷只有CID 能檢測到,而本文工具無法檢測到.這主要是由于2 個工具采用了截然不同的檢測方案,2 個方案適用于不同的場景,都存在一定的局限,因此兩者的檢測范圍既存在重疊又有所不同.這說明本文工作可以和已有檢測工具對內(nèi)核引用計數(shù)缺陷形成檢測能力的互補(bǔ).

Fig.10 Results comparison of bugs detected by our method and CID圖10 本文與 CID 檢測出的缺陷結(jié)果對比

4.5 錯誤路徑識別效果

本文的檢測方案首次將內(nèi)核代碼錯誤故障的語義引入到引用計數(shù)檢測領(lǐng)域.如3.3 節(jié)所述,錯誤路徑的識別是后續(xù)檢測模塊的重要輸入,直接影響了缺陷識別的效果.因此,本文對錯誤路徑識別模塊的效果進(jìn)行了評估.

本文系統(tǒng)在Linux 內(nèi)核版本5.6-rc2 上分析了12 812個函數(shù),其中4 639 個函數(shù)識別到了錯誤路徑(正樣本類),8 173 個函數(shù)上沒有識別到錯誤路徑(負(fù)樣本類).本文工作從這2 類中分別隨機(jī)選取40 個函數(shù)進(jìn)行人工分析,以驗證這些函數(shù)中錯誤路徑的分析結(jié)果.對于每一個函數(shù),本文工作會檢查其所有路徑的識別情況,只要有一條路徑的識別結(jié)果是錯誤的,該函數(shù)就會被歸類為分析錯誤的類.具體結(jié)果如表3 所示.在被取樣的未識別到錯誤路徑的40 個函數(shù)中,有31 個人工確認(rèn)分析正確;在被取樣的未識別到錯誤路徑的40 個函數(shù)中,有32 個人工確認(rèn)分析正確.

Table 3 Effectiveness of Error Path Identification表3 錯誤路徑識別效果

本文也對分析結(jié)果不正確的情況進(jìn)一步深入分析.對于誤報來說,最主要的原因是靜態(tài)分析技術(shù)的不準(zhǔn)確性.有一些不可達(dá)的路徑被錯誤地分析為錯誤處理路徑,或是數(shù)據(jù)流分析的錯誤導(dǎo)致工具誤識別了一些錯誤狀態(tài)碼,進(jìn)而錯誤地標(biāo)記了部分路徑的分類.對于漏報來說,最主要的原因是本文對錯誤路徑的識別策略還不夠健全.在3.3 節(jié)中,處理了4種錯誤故障處理的情況,然而內(nèi)核的錯誤故障處理方式多樣,有許多情況無法被3.3 節(jié)的識別策略覆蓋.但是,如何進(jìn)一步提升錯誤路徑的識別策略并不是本文工作的主要研究工作.

5 總 結(jié)

引用計數(shù)缺陷在內(nèi)核中廣泛存在,對內(nèi)核安全構(gòu)成嚴(yán)重威脅.本文提出了一個新的思路,即從錯誤路徑上的引用計數(shù)操作行為入手.本文觀察到,同一個函數(shù)中的不同錯誤路徑對引用計數(shù)對象有相似的故障處理行為.基于該觀察,本文提出了基于錯誤路徑行為一致性分析的引用計數(shù)缺陷檢測方案,并實現(xiàn)了一個引用計數(shù)缺陷檢測系統(tǒng).對每一個目標(biāo)函數(shù),系統(tǒng)首先識別出其中的錯誤路徑,然后分析路徑上的引用計數(shù)行為,最終基于一致性分析識別出引用計數(shù)相關(guān)行為背離主流傾向的路徑潛在缺陷報告.在實驗中,檢測工具在Linux 內(nèi)核版本5.6-rc2 上和版本5.17 上分別報告了66 個和46 個缺陷,人工確認(rèn)了其中的21 個和9 個.此外,與工具CID 的比較實驗表明,本文工具可以發(fā)現(xiàn)部分已有工具識別范圍外的缺陷,形成檢測能力的互補(bǔ).

作者貢獻(xiàn)聲明:熊忻負(fù)責(zé)論文相關(guān)的方案設(shè)計、代碼實現(xiàn)、實驗測試以及論文撰寫;談心參與了方案設(shè)計與論文撰寫;張源提出指導(dǎo)意見并修改論文.

猜你喜歡
內(nèi)核代碼計數(shù)
古人計數(shù)
強(qiáng)化『高新』內(nèi)核 打造農(nóng)業(yè)『硅谷』
遞歸計數(shù)的六種方式
古代的計數(shù)方法
基于嵌入式Linux內(nèi)核的自恢復(fù)設(shè)計
Linux內(nèi)核mmap保護(hù)機(jī)制研究
創(chuàng)世代碼
創(chuàng)世代碼
創(chuàng)世代碼
創(chuàng)世代碼