亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于配對函數(shù)調(diào)用場景的設(shè)備驅(qū)動漏洞檢測①

        2019-10-18 06:40:46翟高壽李紅輝
        關(guān)鍵詞:函數(shù)調(diào)用驅(qū)動程序調(diào)用

        王 佳,翟高壽,劉 峰,李紅輝

        (北京交通大學(xué) 計(jì)算機(jī)與信息技術(shù)學(xué)院,北京 100044)

        設(shè)備驅(qū)動程序作為操作系統(tǒng)中的重要組成部分,占據(jù)了Linux內(nèi)核源碼約70%的部分.2001年,Chou等人[1]最早通過將靜態(tài)分析器應(yīng)用于Linux 1.0版本至2.4.1版本用以進(jìn)行故障分析,研究表明驅(qū)動程序目錄包含的錯誤比內(nèi)核中的其他目錄多達(dá)7倍.驅(qū)動程序相當(dāng)于一個處于硬件和應(yīng)用程序之間的軟件接口,它負(fù)責(zé)對硬件設(shè)備底層I/O操作進(jìn)行管理,可以將其視為一種內(nèi)核模塊.由于驅(qū)動代碼本身可能存在缺陷和漏洞,設(shè)備驅(qū)動代碼開發(fā)人員通過編譯檢查很難排查到一些特定條件下才會觸發(fā)的代碼錯誤[2].2011年,Chen等人[3]對Linux內(nèi)核中的漏洞做了具體的分析歸納,主要問題表現(xiàn)為內(nèi)核接口誤用、緩沖區(qū)溢出、空指針及指針錯誤、競爭與死鎖、內(nèi)存資源操作不當(dāng)?shù)?其中內(nèi)存資源操作類漏洞作為其中的一種主要安全威脅,嚴(yán)重時甚至可直接造成系統(tǒng)崩潰.

        設(shè)備驅(qū)動程序一般會調(diào)用特定的內(nèi)核接口函數(shù)來申請和釋放資源,我們可稱之為配對函數(shù)[4],這種將資源操作類函數(shù)以成對形式進(jìn)行提取的概念最早來自于Engler等人提出的一種名為ECC[5]的方法,ECC可以提取源代碼中的配對函數(shù)信息,并相應(yīng)地提取潛在地正常執(zhí)行路徑上的路徑規(guī)則.目前對于這類函數(shù)的文檔描述極少,但由于其涉及到內(nèi)存資源的相關(guān)操作,一旦出現(xiàn)資源操作的錯誤,將會危及整個操作系統(tǒng)的安全.因此對于這類函數(shù)的相關(guān)檢測和處理至關(guān)重要.

        現(xiàn)有的主流Linux設(shè)備驅(qū)動程序分析方法主要有動態(tài)分析、靜態(tài)分析以及符號執(zhí)行3種.在如今的程序分析技術(shù)路線中,現(xiàn)有的大多數(shù)漏洞檢測方法主要針對用戶模式下的內(nèi)核API調(diào)用規(guī)則和資源檢測[6],很多方法并不能很好地應(yīng)用于工作在內(nèi)核模式下的設(shè)備驅(qū)動程序上.在程序的安全缺陷檢查方面,動態(tài)分析通常需要在源碼中結(jié)合程序插樁技術(shù)[7],在程序執(zhí)行過程中依據(jù)制定的驗(yàn)證規(guī)則,對執(zhí)行的中間結(jié)果進(jìn)行分析.Zhou等人開發(fā)的SafeDrive[8]原型工具在編譯驅(qū)動程序時,根據(jù)內(nèi)核開發(fā)人員的注釋插入相應(yīng)的檢查規(guī)則,然后在運(yùn)行時驗(yàn)證程序的安全性和完整性.動態(tài)分析不需要對源碼進(jìn)行系統(tǒng)地分析,但也因此達(dá)不到較高的覆蓋程度,且一般情況動態(tài)分析下都依賴于真實(shí)的硬件,這為實(shí)時檢測帶來很多難度.靜態(tài)分析則與動態(tài)分析的分析方向不同,其滿足在不運(yùn)行程序的情況下,通過各種詞法、語法分析等分析技術(shù)來檢測分析源程序的數(shù)據(jù)流或控制流.由于設(shè)備驅(qū)動程序源碼中存在較多的條件分支和循環(huán)語句,靜態(tài)分析可以滿足全覆蓋源碼的條件,不依賴于真實(shí)的硬件設(shè)備,無需考慮很多執(zhí)行過程中的限制因素,但是Linux設(shè)備驅(qū)動的代碼結(jié)構(gòu)十分龐大,去分析其中的源碼結(jié)構(gòu)和庫函數(shù)也是一件費(fèi)時費(fèi)力的事.符號執(zhí)行[9]的分析方法則是用符號值替代具體的程序變量,并對所有可能的執(zhí)行路徑使用約束求解技術(shù)[10]生成特定的路徑約束條件,得到符合條件的程序執(zhí)行路徑.Cadar等人開發(fā)的輕量級符號執(zhí)行工具KLEE[11]可以基于LLVM[12]下的中間語言并對其進(jìn)行符號執(zhí)行,通過程序執(zhí)行狀態(tài)的變化模擬真實(shí)程序的執(zhí)行情況.路徑爆炸是符號執(zhí)行分析技術(shù)中產(chǎn)生的一個最主要的問題,伴隨著符號執(zhí)行分析技術(shù)的發(fā)展,如何更有效地減少路徑分支的指數(shù)增長情況,避免產(chǎn)生路徑爆炸的問題正成為研究熱門.

        以上3類設(shè)備驅(qū)動程序的分析方法都不可能100%覆蓋所有潛在的安全漏洞.目前的設(shè)備驅(qū)動資源漏洞檢測工作大多基于編譯后的中間結(jié)果,耦合度和復(fù)雜程度高,獲取的信息不全面,給漏洞分析檢測任務(wù)帶來許多挑戰(zhàn),并且基于編譯過程中的中間結(jié)果有時不能直觀反映出設(shè)備驅(qū)動程序各函數(shù)的執(zhí)行情況.在本文的工作中,我們提出了基于配對函數(shù)調(diào)用場景的設(shè)備驅(qū)動漏洞檢測方法并設(shè)計(jì)實(shí)現(xiàn)PFED (Pair Function Extraction and Detection)原型,首先是提取配對函數(shù)時優(yōu)化配對的規(guī)則,自動化提取結(jié)合手工分析驗(yàn)證;隨后,在記錄配對函數(shù)各項(xiàng)參數(shù)和調(diào)用信息的基礎(chǔ)上,通過獲取驅(qū)動函數(shù)調(diào)用場景信息以更新配對函數(shù)在驅(qū)動函數(shù)執(zhí)行路徑中調(diào)用的記錄;最終,結(jié)合調(diào)用場景驗(yàn)證并檢測可能存在的內(nèi)存資源的申請和釋放不匹配問題.

        本文的主要貢獻(xiàn)有:預(yù)處理源碼并優(yōu)化提取資源操作類配對函數(shù)的結(jié)果,在驅(qū)動程序配對函數(shù)的互斥語義上做了更進(jìn)一步的擴(kuò)展與驗(yàn)證;提出構(gòu)建配對函數(shù)調(diào)用場景的概念,用于完整記錄配對函數(shù)在執(zhí)行路徑上的對應(yīng)關(guān)系,對源碼的覆蓋程度更高;設(shè)計(jì)并實(shí)現(xiàn)了基于配對函數(shù)調(diào)用場景的設(shè)備驅(qū)動漏洞檢測原型,實(shí)驗(yàn)結(jié)果表明,該方法更適用于對設(shè)備驅(qū)動程序的分析,同時進(jìn)一步降低了漏報(bào)率、誤報(bào)率.

        1 相關(guān)工作

        1.1 靜態(tài)分析

        目前大部分的研究工作主要集中在檢測設(shè)備驅(qū)動漏洞的緩沖區(qū)溢出、整數(shù)溢出等這些溢出問題上,kint[13]是一個用于檢測C語言源程序中出現(xiàn)的整數(shù)溢出錯誤的靜態(tài)分析工具,圖1是其原型架構(gòu)設(shè)計(jì)的流程圖,通過對基于LLVM形成的中間語言和注釋信息的分析、約束求解過程來生成最終的錯誤報(bào)告,可用于分析Linux內(nèi)核,協(xié)助內(nèi)核開發(fā)工作人員檢測程序中出現(xiàn)的整數(shù)溢出錯誤.由于經(jīng)歷了中間語言的重寫和各項(xiàng)元數(shù)據(jù)集中處理的復(fù)雜過程,最后獲取的生成約束表達(dá)式并不十分準(zhǔn)確,kint分析得到的整數(shù)溢出漏洞結(jié)果中存在著較高的誤報(bào)率.除此以外,在設(shè)備驅(qū)動的資源操作類漏洞方面,目前開展的研究工作主要是針對內(nèi)存資源泄露的檢測.

        圖1 Kint原型架構(gòu)設(shè)計(jì)

        1.2 運(yùn)行時分析

        PairDyn[14]是由Bai等人提出的一種運(yùn)行時分析檢測方法,用來檢測設(shè)備驅(qū)動程序中的資源申請和釋放的匹配.

        圖2是PairDyn的架構(gòu)設(shè)計(jì)圖,在驅(qū)動程序運(yùn)行時,PairDyn根據(jù)插入的探針記錄下運(yùn)行時的關(guān)鍵信息,如參數(shù)返回值、函數(shù)調(diào)用信息,再將這些信息與手動篩選得到的驅(qū)動程序配對函數(shù)記錄列表相匹配,獲取相應(yīng)的測試用例,測試對于內(nèi)存資源的申請是否有相應(yīng)的釋放函數(shù)調(diào)用與其對應(yīng).PairDyn是通過人工方式選擇配對函數(shù)的,而人工方式可能會出現(xiàn)一些誤判和遺漏;只能在運(yùn)行時檢查正常情況下的執(zhí)行路徑,因此其不能覆蓋程序中的異常處理路徑以及條件分支路徑.

        圖2 PairDyn架構(gòu)設(shè)計(jì)

        2 設(shè)備驅(qū)動漏洞檢測原型的構(gòu)建

        本文的主要目標(biāo)是先從設(shè)備驅(qū)動源程序中提取出函數(shù)調(diào)用完整信息,優(yōu)化迭代并最終提取出真正的資源操作相關(guān)配對函數(shù),記錄這些函數(shù)的調(diào)用上下文場景,包括函數(shù)的主調(diào)函數(shù)、被調(diào)函數(shù)、參數(shù)返回值等有效信息.在全覆蓋驅(qū)動源碼分析的基礎(chǔ)上,獲取各對配對函數(shù)在驅(qū)動源程序的執(zhí)行路徑分支層級上的調(diào)用關(guān)系是否匹配和對稱.圖3展示了PFED原型系統(tǒng)的設(shè)計(jì),接下來將對該方法涉及到的一些重要部分進(jìn)行介紹說明.

        圖3 原型系統(tǒng)設(shè)計(jì)

        3 設(shè)備驅(qū)動漏洞檢測原型的設(shè)計(jì)與實(shí)現(xiàn)

        為實(shí)現(xiàn)PFED原型,首先要了解聲卡、網(wǎng)卡、USB等常用設(shè)備驅(qū)動的工作流程、功能模塊以及主要程序結(jié)構(gòu).根據(jù)幾個不同類型的典型設(shè)備驅(qū)動分析其源程序結(jié)構(gòu),由于設(shè)備驅(qū)動的源程序代碼結(jié)構(gòu)較為復(fù)雜,代碼量龐大,為了更高效將驅(qū)動源程序中有用的函數(shù)信息提取出來,首先我們要預(yù)處理源程序中的部分信息,在源程序中略去大量注釋、無用的條件預(yù)編譯語句、全局變量定義、結(jié)構(gòu)體定義、宏定義及調(diào)用等冗余信息.在分析設(shè)備驅(qū)動程序?qū)?nèi)核函數(shù)的依賴接口時,主要篩選出頻繁與內(nèi)核函數(shù)交互的設(shè)備驅(qū)動函數(shù)定義進(jìn)行分析,首先手工分析總結(jié)出涉及到內(nèi)存資源操作的一些內(nèi)核函數(shù)并記錄,其次開始著手自動提取驅(qū)動源程序中涉及到這些內(nèi)核函數(shù)的所有函數(shù)原型列表、相關(guān)參數(shù)、調(diào)用關(guān)系、調(diào)用層級、執(zhí)行路徑等重要相關(guān)信息,綜合得出調(diào)用上下文場景.

        整個原型的構(gòu)建及實(shí)現(xiàn)過程簡要?dú)w納說明如下:

        1)分析內(nèi)核模塊的依賴接口,來確定重點(diǎn)提取的內(nèi)核函數(shù)列表;

        2)預(yù)處理驅(qū)動源程序,略去大量無用信息,提取重點(diǎn)函數(shù)原型列表;

        3)設(shè)計(jì)并自動化提取內(nèi)存資源相關(guān)操作的配對函數(shù),手工驗(yàn)證總結(jié)、優(yōu)化糾錯;

        4)創(chuàng)建配對函數(shù)在調(diào)用層級、調(diào)用關(guān)系、調(diào)用路徑等信息的調(diào)用上下文場景;

        5)根據(jù)配對函數(shù)原型列表及調(diào)用上下文場景驗(yàn)證內(nèi)存資源的申請釋放是否嚴(yán)格按層級性匹配.

        3.1 配對函數(shù)提取

        3.1.1 函數(shù)原型列表

        本文使用C語言編寫設(shè)備驅(qū)動源程序預(yù)處理模塊,使后續(xù)需要進(jìn)行深入分析的驅(qū)動函數(shù)提取工作變的更輕量級.主要設(shè)計(jì)的存放函數(shù)原型列表及相關(guān)信息的數(shù)據(jù)結(jié)構(gòu)如下:

        3.1.2 配對函數(shù)識別

        如圖4所示,我們以Linux4.8.8版本內(nèi)核下的pcnet32網(wǎng)卡驅(qū)動程序?yàn)槔?在Linux內(nèi)核機(jī)制中,每個網(wǎng)卡都由一個net_device結(jié)構(gòu)來描述,pcnet32.c中的pcnet32_get_link()函數(shù)是用來判斷當(dāng)前網(wǎng)絡(luò)連接狀態(tài)的驅(qū)動程序,當(dāng)執(zhí)行單元訪問共享資源之前,需要用729行的spin_lock_irqsave來保存中斷標(biāo)志,給中斷當(dāng)前的開啟或關(guān)閉狀態(tài)上鎖,相當(dāng)于失效了當(dāng)前的中斷;而739行的spin_unlock_irqrestore則是要恢復(fù)訪問共享資源前的中斷標(biāo)志,相當(dāng)于釋放掉自旋鎖,恢復(fù)到之前的中斷狀態(tài).Linux內(nèi)核的中斷機(jī)制中大量使用了自旋鎖機(jī)制,可以看出在該函數(shù)體內(nèi)部spin_lock_irqsave和spin_unlock_irqrestore是先后分別被調(diào)用的,它們的調(diào)用次序是固定的,并且有上鎖的操作則必須有解鎖的操作.

        圖4 Linux4.8.8下pcnet32驅(qū)動部分代碼段

        本文主要在靜態(tài)分析方法的基礎(chǔ)上事先通過對設(shè)備驅(qū)動程序源碼進(jìn)行分析處理,得到可能的資源操作配對函數(shù)信息.圖5顯示了在pcnet32網(wǎng)卡驅(qū)動程序的不同函數(shù)定義體下相關(guān)資源操作的函數(shù).pcnet32_probe1()函數(shù)是加載和初始化的網(wǎng)卡驅(qū)動程序,1695行的alloc_etherdev是在該函數(shù)體中創(chuàng)建網(wǎng)絡(luò)設(shè)備,禁用網(wǎng)卡之后,網(wǎng)卡程序則在pcnet32_remove()函數(shù)體內(nèi)調(diào)用2892行的free_netdev刪除已分配的網(wǎng)絡(luò)設(shè)備.這兩個函數(shù)在對網(wǎng)絡(luò)設(shè)備資源操作時呈現(xiàn)申請/釋放的對應(yīng)操作,也即:對內(nèi)存資源申請之后必須相應(yīng)地釋放掉,并且調(diào)用次序和主調(diào)函數(shù)都是固定和相對應(yīng)的.

        圖5 Linux4.8.8下pcnet32驅(qū)動部分代碼段

        3.1.3 獲取配對函數(shù)列表

        Linux內(nèi)核開發(fā)人員對于內(nèi)核函數(shù)的命名是十分規(guī)范的,我們所歸納的這些配對函數(shù)的函數(shù)名是由規(guī)則的語義詞、字符串及下劃線組成的,部分配對函數(shù)名稱由一些加上前綴和后綴的字符串拼接組成,每個字符串由下劃線連接,如圖5所示,整個函數(shù)名不僅僅有release,還有這個關(guān)鍵詞前后的字符串pci和device,因此對于配對函數(shù)的識別就需要進(jìn)行整個字符串語義匹配的綜合判斷.針對預(yù)處理設(shè)備驅(qū)動源程序之后得到的函數(shù)列表,對其進(jìn)行手工分析總結(jié)得到一些涉及到內(nèi)存資源操作,且操作均為對資源的申請/釋放的函數(shù)對,表1列出了一些高頻使用的配對函數(shù)部分關(guān)鍵詞及其相關(guān)描述.

        對于配對函數(shù)的關(guān)鍵詞語義集合構(gòu)建,需要包含全部內(nèi)核函數(shù)資源操作的關(guān)鍵詞并歸納出每一對具有相反語義的關(guān)鍵詞對.我們給出配對函數(shù)的判定條件如下:

        1)對于資源進(jìn)行操作的函數(shù)名滿足一定的命名規(guī)則;

        2)對內(nèi)存中相同的資源進(jìn)行操作,且操作的語義是相反的;

        3)成對地出現(xiàn)在一個完整的驅(qū)動程序執(zhí)行場景中.

        針對以上配對函數(shù)的判定條件,提取配對函數(shù)需要建立兩個存放不同語義的關(guān)鍵詞集,將手工分析得出的關(guān)鍵詞分別放入兩個關(guān)鍵詞集中.

        表1 配對函數(shù)關(guān)鍵詞描述

        圖6給出了提取配對函數(shù)的算法.

        圖6 提取配對函數(shù)算法

        根據(jù)以上的對配對函數(shù)的介紹和判定條件,對配對函數(shù)的提取和匹配主要有圖6中所描述的以下幾個關(guān)鍵過程:首先創(chuàng)建兩個關(guān)鍵詞集分別為內(nèi)存資源申請關(guān)鍵詞集requestSet、內(nèi)存資源釋放關(guān)鍵詞集releaseSet,以及一個配對函數(shù)詞集pairSet.針對遍歷預(yù)處理設(shè)備驅(qū)動源程序之后得到的函數(shù)原型列表文件,掃描得到配對函數(shù)詞集中的關(guān)鍵詞記錄,以此來進(jìn)一步發(fā)掘可能需要處理的函數(shù)名列表.對于關(guān)鍵詞記錄表中每個關(guān)鍵字段,將其分別和內(nèi)存資源申請關(guān)鍵詞集 requestSet、內(nèi)存資源釋放關(guān)鍵詞集releaseSet相匹配,以此判斷它是否為資源操作相關(guān)函數(shù)的關(guān)鍵字段.然后,對每個存在配對可能性的資源申請函數(shù)func之后,我們遍歷檢查找出與之對應(yīng)的函數(shù)func_nt.如果func_nt是func的配對函數(shù),則它必須首先必須是一個資源釋放函數(shù),并與函數(shù)func對相同的內(nèi)存數(shù)據(jù)進(jìn)行操作.接著我們對資源釋放函數(shù)func_nt以及資源申請函數(shù)func的匹配程度進(jìn)行計(jì)算,兩個函數(shù)名配對的關(guān)聯(lián)性決定了匹配度,計(jì)算主要過程如下:

        1)初始的匹配度D設(shè)為內(nèi)存資源申請/釋放關(guān)鍵詞集在關(guān)鍵詞完全匹配的狀態(tài)下的匹配度;

        2)若關(guān)鍵詞所在函數(shù)名為單個字符串,直接計(jì)算對應(yīng)的匹配度,匹配失敗則匹配度D為0;

        3)若關(guān)鍵詞是多組字符串和下劃線構(gòu)成的函數(shù)名,對關(guān)鍵詞所在函數(shù)名的字段進(jìn)行分割,若都含有更多相同的子串則匹配度越高,若子串不完全相同則匹配兩個函數(shù)名的最長子串,根據(jù)相應(yīng)結(jié)果計(jì)算不同的匹配度D.

        根據(jù)每一對資源操作函數(shù)func與func_nt,匹配度D超過設(shè)置的閾值D,則配對成功,添加到配對函數(shù)對當(dāng)中;匹配度小于設(shè)定閾值D的函數(shù),根據(jù)最后得到的配對程度報(bào)告文件,對匹配程度低的資源操作函數(shù)對進(jìn)行人工檢查驗(yàn)證,來確認(rèn)其是否為真正的配對函數(shù).通過多次挖掘并修正結(jié)果,優(yōu)化子串的匹配過程,找出真正對內(nèi)存資源進(jìn)行操作的配對函數(shù),可以為后續(xù)檢查函數(shù)調(diào)用關(guān)系和路徑工作減少大量不必要的工作量,從而更高效全面地來檢測設(shè)備驅(qū)動中內(nèi)存資源操作的潛在違規(guī)行為:如果當(dāng)前的函數(shù)是配對函數(shù)詞集PairSet里的一個資源申請函數(shù)func,搜索pairSet中是否有與其對應(yīng)的、對相同數(shù)據(jù)進(jìn)行操作的資源釋放函數(shù)func_nt,如果未找到滿足條件的函數(shù),此時極有可能出現(xiàn)內(nèi)存資源的違規(guī)操作現(xiàn)象.

        3.2 配對函數(shù)調(diào)用上下文場景

        3.2.1 調(diào)用關(guān)系與調(diào)用層級

        本階段的任務(wù)主要是獲取各驅(qū)動函數(shù)的調(diào)用情況、內(nèi)存資源操作函數(shù)的調(diào)用關(guān)系以及調(diào)用層級,建立并維護(hù)每個資源操作函數(shù)的在各個驅(qū)動函數(shù)體內(nèi)部的調(diào)用狀態(tài)列表以及跨驅(qū)動函數(shù)調(diào)用情況下的調(diào)用狀態(tài)列表.該階段主要設(shè)計(jì)的函數(shù)調(diào)用原型列表及相關(guān)信息的數(shù)據(jù)結(jié)構(gòu)如下:

        其中ContextOfInvokingFunction里mContextLevel為當(dāng)前的調(diào)用層級,也就是在源程序里的驅(qū)動函數(shù)體內(nèi)或函數(shù)間的整個調(diào)用關(guān)系中,按照操作的次序來給資源申請函數(shù)/資源釋放函數(shù)編號,并且在每個資源操作函數(shù)的狀態(tài)列表中記錄當(dāng)前的條件分支.如圖7(a)的函數(shù)調(diào)用簡略示意代碼段所示,在整個調(diào)用層級模式以及條件語句結(jié)構(gòu)的基礎(chǔ)上構(gòu)建邏輯次序,a_alloc()~f_alloc()表示資源申請函數(shù),a’_free()~f’_free()表示資源釋放函數(shù),根據(jù)調(diào)用關(guān)系及其對稱性,可以大致歸結(jié)出:在每個完整的程序分支中,配對函數(shù)的調(diào)用必須是成對的,對于某一內(nèi)存資源,有申請必有釋放;在調(diào)用層級上,每個資源操作函數(shù)列表及該函數(shù)下列表的調(diào)用關(guān)系是對稱的,因?yàn)閷τ趦?nèi)存資源滿足先申請后釋放的次序,若驅(qū)動函數(shù)申請資源失敗,必須確保執(zhí)行到最后可以把該資源申請操作之前的所申請的內(nèi)存資源按照對稱的次序全部釋放掉,以確保沒有資源操作的漏洞,驅(qū)動源程序中的多重分支也是如此.圖7(a)代碼段所對應(yīng)的整個資源操作函數(shù)調(diào)用的次序如圖7(b)所示.

        圖7 函數(shù)層級示例

        在與內(nèi)核進(jìn)行交互時,設(shè)備驅(qū)動程序可能會遇到突發(fā)的異常情況.為了保證設(shè)備驅(qū)動代碼的可靠性,必須要提供處理這些突發(fā)情況的異常處理代碼分支.因此,大多數(shù)設(shè)備驅(qū)動程序都會在這種情況下有對應(yīng)的異常處理代碼.多數(shù)設(shè)備驅(qū)動程序基本都是用C語言編寫的,因此無法使用C ++和Java中的一些異常處理或垃圾回收機(jī)制.在設(shè)備驅(qū)動程序中最常用的異常處理機(jī)制就是基于goto語句的代碼異常處理機(jī)制[15].在該機(jī)制中,goto語句用于處理不同狀況下的異常,并且所有異常處理代碼基本都位于每個設(shè)備驅(qū)動函數(shù)體內(nèi)的末尾位置,放置于每一個獨(dú)立的代碼段中.例如圖5中,當(dāng)1695行的申請以太網(wǎng)設(shè)備函數(shù)alloc_etherdev()返回異常時,驅(qū)動程序?qū)D(zhuǎn)到1951行起始的err_release_region代碼段.

        在異常處理代碼段中的每個資源釋放函數(shù)都應(yīng)該與該狀態(tài)前的正常執(zhí)行的資源申請函數(shù)形成層級性配對,也即必須在異常處理部分逆序釋放當(dāng)前調(diào)用狀態(tài)列表中所有已分配內(nèi)存資源的申請函數(shù).

        在異常處理代碼段中的每個資源釋放函數(shù)都應(yīng)該與該狀態(tài)前的正常執(zhí)行的資源申請函數(shù)形成層級性配對,也即必須在異常處理部分逆序釋放當(dāng)前調(diào)用狀態(tài)列表中所有已分配內(nèi)存資源的申請函數(shù).

        3.2.2 建立執(zhí)行路徑

        本階段的任務(wù)是基于每個資源操作函數(shù)的調(diào)用狀態(tài)列表建立完整的配對函數(shù)執(zhí)行路徑.如果函數(shù)調(diào)用列表中的某個驅(qū)動函數(shù)體內(nèi)沒有調(diào)用其他驅(qū)動函數(shù),就只在該驅(qū)動函數(shù)體內(nèi)建立配對函數(shù)的執(zhí)行路徑,如果存在其他驅(qū)動函數(shù),則需要跨函數(shù)建立配對函數(shù)的整個執(zhí)行路徑.

        針對單個驅(qū)動函數(shù)體內(nèi)建立配對函數(shù)執(zhí)行路徑的情況,首先要從調(diào)用狀態(tài)列表取出當(dāng)前資源申請函數(shù)調(diào)用起始位置所在的驅(qū)動函數(shù),也即其主調(diào)函數(shù)信息;然后依據(jù)該驅(qū)動函數(shù)體內(nèi)相應(yīng)的最近層級配對函數(shù)調(diào)用狀態(tài)列表提取出語義相反的資源釋放函數(shù),綜合二者調(diào)用狀態(tài)列表中的調(diào)用層級(驅(qū)動函數(shù)體內(nèi)首個資源申請函數(shù)和最后一個資源釋放函數(shù),對應(yīng)層級為0層)、操作參數(shù),在執(zhí)行過程中每多加載一個資源申請函數(shù),則對應(yīng)層級加1,而資源釋放函數(shù)則是每多加載一個則層級減1.最后分析完畢之后若形成完全對稱性匹配,就綜合這些配對函數(shù)的狀態(tài)形成一條資源申請與釋放的完整路徑信息,整個調(diào)用路徑記錄對應(yīng)著驅(qū)動源程序中的行號.若遍歷整個函數(shù)體內(nèi)未找到對應(yīng)層級的資源釋放函數(shù),則形成不完整路徑的報(bào)告.

        在分析完單個驅(qū)動函數(shù)體內(nèi)的執(zhí)行路徑之后,則需要針對跨驅(qū)動函數(shù)的情況建立配對函數(shù)執(zhí)行路徑.此時,如圖7(b)所示,會有一個分析調(diào)用路徑入口的主函數(shù)h,在該驅(qū)動主函數(shù)體內(nèi),每當(dāng)分析到出現(xiàn)對另外的驅(qū)動函數(shù)進(jìn)行調(diào)用的情況,此時要從函數(shù)調(diào)用狀態(tài)列表中提取并記錄調(diào)用的位置,然后提取被調(diào)用驅(qū)動函數(shù)體中的配對函數(shù)列表,載入該列表信息后,再綜合當(dāng)前的主函數(shù)建立配對函數(shù)總的執(zhí)行路徑.

        在得到了每個驅(qū)動函數(shù)體內(nèi)的配對函數(shù)并確立了每個資源操作函數(shù)的對應(yīng)層級、調(diào)用信息、相關(guān)參數(shù)之后,對配對函數(shù)集合中的申請資源函數(shù)名進(jìn)行遍歷時,從每個資源申請函數(shù)開始作為根節(jié)點(diǎn),子節(jié)點(diǎn)和葉節(jié)點(diǎn)分別定義為資源申請函數(shù)涉及的內(nèi)存變量、執(zhí)行路徑終點(diǎn)的資源釋放函數(shù)和相關(guān)參數(shù).從根節(jié)點(diǎn)開始依次往后搜索尋找子節(jié)點(diǎn)、葉節(jié)點(diǎn),對于每個子節(jié)點(diǎn),重復(fù)進(jìn)行向后搜索的流程直到抵達(dá)葉節(jié)點(diǎn),最終得出每條完整的執(zhí)行路徑集合及其所對應(yīng)的資源操作集合.因此每條完整的路徑集合可以看做一棵包含參數(shù)信息的以順序執(zhí)行序列構(gòu)成的結(jié)構(gòu)化數(shù)據(jù)流樹,每棵由最外層資源申請函數(shù)作為數(shù)據(jù)流起點(diǎn)的樹中包含了其內(nèi)部所有以被調(diào)資源申請函數(shù)為起點(diǎn)的子樹,子樹數(shù)量為n.每棵樹的深度為d,d的值為滿足以下條件的最小值:

        將真實(shí)的執(zhí)行路徑集合占整個路徑數(shù)量的比例λ進(jìn)行統(tǒng)計(jì),由于實(shí)驗(yàn)的源碼量大,λ的值一般均不超過20%,并且λ越小,子樹數(shù)量n越小,相應(yīng)的平均執(zhí)行時間越少.因此在各運(yùn)行路徑上構(gòu)造數(shù)據(jù)流樹的平均執(zhí)行時間都是比較少的,基本上處于平穩(wěn)增加的狀態(tài),整個數(shù)據(jù)流樹的構(gòu)造過程不會造成樹的深度d取值過大的問題.

        3.2.3 內(nèi)存資源操作違規(guī)性檢測

        上述PFED原型方法主要是建立在對設(shè)備驅(qū)動源碼進(jìn)行靜態(tài)分析的基礎(chǔ)上去實(shí)現(xiàn)的,在提取驅(qū)動源程序中的配對函數(shù)之后,再針對性的對預(yù)處理之后的源程序分析獲取每個資源操作函數(shù)的調(diào)用上下文場景信息,最后建立多條完整的配對函數(shù)執(zhí)行路徑.在驗(yàn)證設(shè)備驅(qū)動內(nèi)存資源申請釋放的層級匹配過程中,要注意的一點(diǎn)是,同類設(shè)備驅(qū)動程序大多數(shù)情況下的執(zhí)行邏輯相同,例如網(wǎng)卡設(shè)備驅(qū)動的整個工作流程基本上遵循這樣的流程:探測、啟動、發(fā)送和接受數(shù)據(jù)包、關(guān)閉、注銷.因此對于驅(qū)動函數(shù)體的整個檢測順序和每個驅(qū)動函數(shù)調(diào)用場景的建立也要遵循具體的運(yùn)行邏輯.

        通過對Linux2.6.20及 4.8.8內(nèi)核版本下的網(wǎng)卡、聲卡、USB等設(shè)備驅(qū)動源程序的分析處理,我們在多次修正了子串的匹配過程及調(diào)整了匹配閾值T之后,綜合各驅(qū)動程序中的提取配對函數(shù)結(jié)果,PFED分別可提取出共計(jì)54和57對由不同前綴或后綴字符、關(guān)鍵詞以及下劃線組成的配對函數(shù),然后通過人工檢查驗(yàn)證,分別確定了49和52對真正的配對函數(shù).

        在結(jié)合配對函數(shù)調(diào)用狀態(tài)列表之后,最后確立的不完整調(diào)用場景報(bào)告在整個函數(shù)執(zhí)行場景報(bào)告中大約占據(jù)約2.5%的比例.如圖8所示的Linux下的USB設(shè)備驅(qū)動代碼段示例中,存在配對函數(shù)在調(diào)用層級上不匹配的異常情況:在驅(qū)動函數(shù)zd_op_start ()中的

        332 行、334行、336行處的異常處理代碼中,分別調(diào)用了資源釋放函數(shù),這三處釋放函數(shù)嚴(yán)格按調(diào)用層級與前面的資源申請函數(shù)zd_chip_enable_rxtx(),zd_chip_switch_radio_on(),zd_chip_enable_int()相對應(yīng),若申請資源失敗,則跳轉(zhuǎn)到異常處理部分把前面調(diào)用的資源申請函數(shù)按照對稱的次序釋放掉.但是在正常執(zhí)行路徑上,與zd_op_start()所對應(yīng)的驅(qū)動關(guān)閉函數(shù)zd_op_stop()中的zd_chip_disable_rxtx(),zd_chip_disable_hwint()這兩處的釋放函數(shù)的層級顛倒了,由于先調(diào)用了zd_chip_switch_radio_off釋放函數(shù),可能導(dǎo)致 zd_chip_disable_rxtx釋放函數(shù)引發(fā)內(nèi)存資源操作不當(dāng)?shù)膯栴},進(jìn)一步造成死鎖狀態(tài).

        圖8 Linux4.8.8下via-rhine驅(qū)動部分代碼段

        4 實(shí)驗(yàn)結(jié)果與分析

        4.1 實(shí)驗(yàn)方法

        1)實(shí)驗(yàn)環(huán)境:硬件環(huán)境為Intel(R)Core(TM)i7-4710MQ CPU @ 2.50 GHz,8.00 GB內(nèi)存,500 GB硬盤;軟件環(huán)境為Ubuntu 14.04 LTS操作系統(tǒng);開發(fā)和編譯工具為Gedit、GCC4.8,C語言.

        2)實(shí)驗(yàn)樣本:本實(shí)驗(yàn)使用Linux內(nèi)核版本為4.8.8下的六個網(wǎng)卡、聲卡及USB驅(qū)動:pcnet32,ens1370,e100,sky2,zd_mac以及 via-rhine.

        針對設(shè)備驅(qū)動內(nèi)存資源申請與釋放相關(guān)操作的檢測問題,我們將本文提出的PFED原型工具在不同種類設(shè)備驅(qū)動程序上進(jìn)行了測試比較,實(shí)驗(yàn)展示了在6個不同的測試用例上最終分析得到結(jié)果與人工分析得到結(jié)果之間的誤差,進(jìn)行準(zhǔn)確性與可靠性評估.其中對于提取配對函數(shù)實(shí)驗(yàn)的結(jié)果,漏報(bào)率(false negative)指標(biāo)是對比手工分析結(jié)果,最終自動提取結(jié)果中未出現(xiàn)的配對函數(shù)對數(shù)占實(shí)際配對函數(shù)對數(shù)的比例;誤報(bào)率(false positive)指標(biāo)是對比兩份配對函數(shù)結(jié)果報(bào)告,自動提取結(jié)果中含有手工分析報(bào)告未出現(xiàn)的配對函數(shù)對數(shù)占實(shí)際配對函數(shù)對數(shù)的比例.

        4.2 實(shí)驗(yàn)結(jié)果及分析

        通過在不同類型的設(shè)備驅(qū)動程序上提取到的配對函數(shù)對數(shù)與手工分析得到的真實(shí)結(jié)果進(jìn)行對比,以及對最后結(jié)果的漏報(bào)率、誤報(bào)率進(jìn)行統(tǒng)計(jì),來評估本方法的準(zhǔn)確性.

        針對預(yù)處理源程序提取的配對函數(shù)結(jié)果如表2所示,按照對每個驅(qū)動函數(shù)體內(nèi)不去重的方式記錄提取結(jié)果.由表2可以看出,由于本文提出的方法是在對源碼的高覆蓋程度下進(jìn)行分析,并且多次糾正優(yōu)化了函數(shù)名子串匹配過程,通過人工驗(yàn)證檢測結(jié)果,最終結(jié)果的漏報(bào)率和誤報(bào)率都比較低,均不超過15%.

        表2 提取配對函數(shù)結(jié)果

        本方法的可靠性通過對不同版本下的驅(qū)動源程序的漏洞檢測結(jié)果報(bào)告和人工驗(yàn)證真實(shí)的設(shè)備驅(qū)動資源操作漏洞結(jié)果進(jìn)行對比評估,結(jié)果如表3所示.

        表3 漏洞檢測部分結(jié)果

        實(shí)驗(yàn)檢測到的跨驅(qū)動函數(shù)調(diào)用配對函數(shù)情況共22例,由于驅(qū)動程序特有的結(jié)構(gòu)性基礎(chǔ),在靜態(tài)分析過程中涉及到的跨函數(shù)調(diào)用場景配對檢查情況,我們在此處花費(fèi)了更多的人工驗(yàn)證時間.基于我們提取出的全部配對函數(shù)列表,以及建立的函數(shù)調(diào)用場景,根據(jù)不同的調(diào)用層級和申請釋放層級,形成對應(yīng)層級的資源操作漏洞檢測結(jié)果.表3中給出了部分檢測報(bào)告,其中對應(yīng)層級表示的是該對資源操作函數(shù)處于函數(shù)體的哪一層.最終總計(jì)得到了6處可能出現(xiàn)資源匹配問題的有關(guān)漏洞檢測結(jié)果,經(jīng)過人工驗(yàn)證,發(fā)現(xiàn)有1處誤報(bào),1處漏報(bào).因此該方法在滿足對源程序的高覆蓋度情況下,可以有效地檢測出潛在的設(shè)備驅(qū)動資源操作漏洞.

        由于部分設(shè)備驅(qū)動函數(shù)的調(diào)用列表有時會不滿足規(guī)范的資源操作邏輯流程、驅(qū)動函數(shù)出現(xiàn)的個別接口函數(shù)私有化命名現(xiàn)象、驅(qū)動程序設(shè)計(jì)開發(fā)時違背編碼規(guī)范等問題,會導(dǎo)致分析結(jié)果中出現(xiàn)誤判.一些設(shè)備驅(qū)動程序中用以獲取當(dāng)前設(shè)備狀態(tài)的內(nèi)核接口函數(shù),比如netif_carrier_ok/netif_carrier_on/netif_carrier_off這組用來判斷網(wǎng)絡(luò)通路是否為正常連接狀態(tài)的接口函數(shù),網(wǎng)卡驅(qū)動會通過它們和內(nèi)核中的網(wǎng)絡(luò)子系統(tǒng)傳遞消息,但是這些接口函數(shù)并未涉及到內(nèi)存資源操作.因此在檢測過程中我們會剔除這些無法應(yīng)用正常分析流程的特殊實(shí)例,在關(guān)鍵詞集中建立特殊名單機(jī)制并通過迭代檢測結(jié)果更新名單以提高整個檢測過程的效率,降低誤判率.

        5 結(jié)論與展望

        本文提出一種基于配對函數(shù)調(diào)用場景的設(shè)備驅(qū)動漏洞檢測的研究方法及相關(guān)原型PFED,與現(xiàn)有的驅(qū)動漏洞檢測方法相比,我們的方法不依賴于編譯后形成的中間語言和真實(shí)情境下的硬件設(shè)備,在結(jié)合了設(shè)備驅(qū)動工作流程及相關(guān)調(diào)用函數(shù)信息的基礎(chǔ)之后,主要針對提取出的配對函數(shù)在執(zhí)行路徑上的調(diào)用場景信息,增加了需要進(jìn)行分析的信息量,并有效檢測出配對函數(shù)在調(diào)用層級上不匹配的潛在驅(qū)動漏洞.實(shí)驗(yàn)結(jié)果表明,PFED提取的配對函數(shù)結(jié)果更為精確,具有較低的漏報(bào)率、誤報(bào)率,在檢測設(shè)備驅(qū)動資源操作漏洞方面具有較高的可靠性,并且進(jìn)一步提高了源程序的覆蓋度和檢測的準(zhǔn)確度.然而,本文的方法也存在許多不足,對于配對函數(shù)篩選結(jié)果中匹配度低的函數(shù)需要人工檢查驗(yàn)證,今后的研究應(yīng)考慮設(shè)置自動驗(yàn)證和糾錯反饋機(jī)制,將匹配度低的配對函數(shù)分類別處理,使配對函數(shù)提取的整個過程實(shí)現(xiàn)完全自動化.并且如何進(jìn)一步地結(jié)合更多種類的設(shè)備驅(qū)動結(jié)構(gòu)、將符號執(zhí)行技術(shù)應(yīng)用于函數(shù)調(diào)用場景中以提高檢測效率,也將成為未來的研究工作.

        猜你喜歡
        函數(shù)調(diào)用驅(qū)動程序調(diào)用
        基于C語言的數(shù)學(xué)菜單的設(shè)計(jì)與實(shí)現(xiàn)
        核電項(xiàng)目物項(xiàng)調(diào)用管理的應(yīng)用研究
        LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
        基于函數(shù)調(diào)用序列模式和函數(shù)調(diào)用圖的程序缺陷檢測方法*
        探討C++編程中避免代碼冗余的技巧
        Unity3D項(xiàng)目腳本優(yōu)化分析與研究
        中國新通信(2017年1期)2017-03-08 03:12:21
        基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
        利用RFC技術(shù)實(shí)現(xiàn)SAP系統(tǒng)接口通信
        驅(qū)動程序更新與推薦
        驅(qū)動程序更新與推薦
        91免费永久国产在线观看| 人妻少妇-嫩草影院| 色婷婷综合久久久久中文字幕| 亚洲最大天堂无码精品区| 日韩中文字幕网站| 亚洲1区第2区第3区在线播放| 亚洲av无码电影在线播放| 香蕉久久久久久久av网站| 亚洲国产精品综合久久20| h视频在线免费观看视频| 俺去啦最新地址| 人人妻人人爽人人做夜欢视频九色 | 亚洲熟女少妇精品综合| 中文字幕人妻熟在线影院| 97se在线| 色婷婷久久99综合精品jk白丝| 精品国产一区二区三区18p| 久久成人国产精品| 亚洲精品有码在线观看| 国产自产在线视频一区| 日韩精品综合一本久道在线视频| 狠狠噜天天噜日日噜视频麻豆| 国产精品丝袜在线不卡| 久久91精品国产91久久跳舞| 国产午夜免费高清久久影院| 欧美丰满大屁股ass| 超碰观看| 一区二区三区四区中文字幕av| 男女后进式猛烈xx00动态图片| 亚洲色婷婷免费视频高清在线观看| 中文字幕视频二区三区| 黑人巨大精品欧美| 免费观看a级毛片| 欧美人与动人物姣配xxxx| 国产国拍亚洲精品永久69| 无人视频在线播放免费| 国产啪亚洲国产精品无码| 国产亚洲精品看片在线观看| 亚洲大胆视频在线观看| 国产丝袜美女| 欧美人与物videos另类xxxxx|