專利名稱:用于源代碼檢測源代碼中弱點(diǎn)的方法和裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計(jì)算機(jī)系統(tǒng)安全,尤其涉及檢測可能造成安全風(fēng)險(xiǎn)的計(jì)算機(jī)源代碼弱點(diǎn)的方法和系統(tǒng)。
背景技術(shù):
與開發(fā)計(jì)算機(jī)程序相關(guān)聯(lián)的問題之一是檢測程序中的“弱點(diǎn)”的困難。當(dāng)在此使用時(shí),術(shù)語“弱點(diǎn)”是指在執(zhí)行時(shí)有可能使外部輸入能導(dǎo)致不適當(dāng)?shù)幕蚍穷A(yù)期的運(yùn)行的用戶源代碼的一部分。典型的弱點(diǎn)包括緩沖器溢出、紊亂情況、特許升級,其中每一個(gè)都會給程序的期望受控運(yùn)行造成弱點(diǎn)。查看源代碼以找出弱點(diǎn)是一個(gè)困難而又費(fèi)時(shí)的過程。它需要對全部潛在弱點(diǎn)、怎樣發(fā)現(xiàn)它們,以及怎樣修復(fù)它們有全面的理解。
檢測源代碼中的弱點(diǎn)的現(xiàn)有方法包括實(shí)施源代碼的詞法分析。這涉及實(shí)施對眾所周知的弱點(diǎn)的搜索,并將其指為潛在弱點(diǎn)。該方法的一個(gè)問題在于它會產(chǎn)生太多的假陽性。另一種方法需要實(shí)施對代碼的人工的逐行分析。但是,這種方法勞動強(qiáng)度太大。
發(fā)明內(nèi)容
本發(fā)明提供一種用于檢測源代碼中的弱點(diǎn)的方法和系統(tǒng)。
本發(fā)明的一方面中,提供了一種檢測源代碼中的弱點(diǎn)的方法和系統(tǒng),包括以下步驟分析源代碼中的變量并且創(chuàng)建模型,其中每個(gè)模型指定有關(guān)每個(gè)變量的預(yù)定特征;使用變量模型來源代碼創(chuàng)建源代碼中例程調(diào)用的自變量模型;并且結(jié)合相應(yīng)例程調(diào)用的預(yù)定標(biāo)準(zhǔn)使用該自變量模型,來確定例程調(diào)用是否具有因自變量和已知例程行為而引起的弱點(diǎn)。
本發(fā)明的另一方面中,提供了一種檢測源代碼中弱點(diǎn)的方法和系統(tǒng),包括以下步驟產(chǎn)生描述有關(guān)例程流的某些特征的模型,并且結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用該模型,來確定例程調(diào)用是否具有因該例程流引起的弱點(diǎn)。
本發(fā)明的又一方面中,提供了一種檢測源代碼中弱點(diǎn)的方法,包括以下步驟產(chǎn)生描述有關(guān)要在例程中執(zhí)行的動作的某些特征的模型,并且結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用該模型,來確定例程調(diào)用是否具有可使例程中的動作在期望設(shè)計(jì)外執(zhí)行的弱點(diǎn)。
在附圖中,圖1示出根據(jù)本發(fā)明一實(shí)施例的系統(tǒng)和方法的各個(gè)步驟的流程圖;圖2示出整數(shù)點(diǎn)陣的一個(gè)示例;圖3示出存儲器尺寸點(diǎn)陣的一個(gè)示例;圖4示出數(shù)據(jù)尺寸點(diǎn)陣的一個(gè)示例;圖5示出無效終止點(diǎn)陣的一個(gè)示例;圖6示出存儲器位置點(diǎn)陣的一個(gè)示例;圖7示出字符串值點(diǎn)陣的一個(gè)示例;圖8示出數(shù)據(jù)源點(diǎn)陣的一個(gè)示例;圖9示出根據(jù)本發(fā)明一實(shí)施例的流非敏感分析(Flow-Insensitive Analysis)所執(zhí)行的各個(gè)步驟的流程圖;圖10A-B示出根據(jù)本發(fā)明一實(shí)施例的流非敏感分析的在處理表達(dá)式中所執(zhí)行的各個(gè)步驟的流程圖;圖11A-B示出根據(jù)本發(fā)明一實(shí)施例的調(diào)用點(diǎn)分析(Call Site Analysis)的在處理表達(dá)式中所執(zhí)行的各個(gè)步驟的流程圖;圖12示出根據(jù)本發(fā)明一實(shí)施例的控制流圖表;圖13示出本發(fā)明一實(shí)施例的系統(tǒng)和方法的各個(gè)步驟的流程圖。
具體實(shí)施例方式
本發(fā)明的較佳實(shí)施例提供了用于檢測源代碼中弱點(diǎn)的方法和系統(tǒng)。此處所用的術(shù)語“弱點(diǎn)”是指在執(zhí)行時(shí)有可能使外部輸入能導(dǎo)致不合適或不期望的執(zhí)行的用戶源代碼的一部分。
本發(fā)明的較佳實(shí)施例提供了用于檢測諸如緩沖器溢出、紊亂情況和特許升級的弱點(diǎn)的方法和系統(tǒng)。
圖13是示出用于分析計(jì)算機(jī)程序以檢測諸如緩沖器溢出、紊亂情況和特許升級的弱點(diǎn)的示例性邏輯的流程圖。該處理有兩個(gè)基塊語言特定處理和弱點(diǎn)分析。語言特定處理分析源代碼并創(chuàng)建模型。語言特定處理首先以語言解析器136開始,它接收要分析的源代碼134并從中創(chuàng)建中間表達(dá)(IR)。IR是本領(lǐng)域眾所周知的,因而在此不描述解析邏輯。
模型138被創(chuàng)建來描述源代碼的某些特征,并且該模型在弱點(diǎn)評估140中結(jié)合弱點(diǎn)數(shù)據(jù)庫142使用,以確定是否有弱點(diǎn)存在。
圖1是示出根據(jù)本發(fā)明某些實(shí)施例的用于為緩沖器溢出弱點(diǎn)分析計(jì)算機(jī)程序的示例性邏輯的流程圖。該處理有兩個(gè)基塊語言特定處理和弱點(diǎn)分析。
該語言特定處理分析源代碼并建模用于調(diào)用選擇過程、函數(shù)或例程的自變量。該模型使用稱為“弱點(diǎn)點(diǎn)陣”的獨(dú)特結(jié)構(gòu)。該弱點(diǎn)點(diǎn)陣用于指定有關(guān)諸如其存儲器尺寸、存儲器類型等的自變量(不論是變量或表達(dá)式)的某些相關(guān)信息。該點(diǎn)陣規(guī)范是語言無關(guān)的。
弱點(diǎn)分析使用弱點(diǎn)點(diǎn)陣和其它信息來分析帶有這種自變量的這種例程調(diào)用的影響。該分析是語言無關(guān)的。該分析應(yīng)用規(guī)則來確定,源代碼中的給定例程調(diào)用,包括該調(diào)用中使用的自變量,是否造成了某些錯誤類型的內(nèi)在弱點(diǎn)或風(fēng)險(xiǎn)。例如,該分析可確定,在源代碼中給定位置的帶有特定自變量的特定例程調(diào)用產(chǎn)生了緩沖器溢出錯誤的潛在可能。
語言特定處理和弱點(diǎn)評估都利用點(diǎn)陣結(jié)構(gòu)來建模和分析可用作例程自變量的變量或表達(dá)式。作為背景,點(diǎn)陣表示有關(guān)實(shí)體的值的認(rèn)知的明確表達(dá)。圖2示出整數(shù)值的整數(shù)點(diǎn)陣22的一個(gè)示例。在點(diǎn)陣頂部的頂端值()表示不知道該值。在點(diǎn)陣底部的底端值()表示一未知值(例如,沒有對有關(guān)應(yīng)當(dāng)應(yīng)用哪個(gè)可能值的解析)。在頂端值和底端值之間的各個(gè)值表示實(shí)體的可能值。在圖2所示的整數(shù)點(diǎn)陣中,整數(shù)0、1、2、3、4和5是實(shí)體的可能值。
創(chuàng)建自變量的弱點(diǎn)點(diǎn)陣以選擇例程的語言特定處理語言特定處理首先以語言解析器12開始,它接收要分析的源代碼10并從中創(chuàng)建中間表達(dá)(IR)。
流非敏感分析14分析該IR,并導(dǎo)出有關(guān)代碼中每個(gè)變量的模型。這些模型以點(diǎn)陣形式指定并被稱為弱點(diǎn)點(diǎn)陣。(這些點(diǎn)陣一般是眾所周知的。)在較佳實(shí)施例中,弱點(diǎn)點(diǎn)陣(在下面的段落里有時(shí)也稱為“表達(dá)式點(diǎn)陣”)包括描述變量或表達(dá)式(取決于該弱點(diǎn)點(diǎn)陣是否與變量或表達(dá)式相關(guān)聯(lián))的重要特征的多個(gè)其它點(diǎn)陣。更具體地,弱點(diǎn)點(diǎn)陣提供有關(guān)如下的信息
·存儲器尺寸;·數(shù)據(jù)尺寸;·數(shù)據(jù)是否無效終止;·存儲器塊中包含的存儲器種類;·存儲器塊的一個(gè)或多個(gè)常量字符串值以及·數(shù)據(jù)源。
當(dāng)確定應(yīng)如何設(shè)置或修改點(diǎn)陣時(shí),流非敏感分析邏輯將預(yù)定合并規(guī)則應(yīng)用于各種點(diǎn)陣類型。這在例如分析表達(dá)式時(shí)使用。
流非敏感分析邏輯還利用整數(shù)點(diǎn)陣來描述整數(shù)類型變量(仍以點(diǎn)陣形式)。
圖3示出存儲器尺寸點(diǎn)陣24的示例。存儲器尺寸點(diǎn)陣24是包括值高、低以及一對非負(fù)整數(shù)值的點(diǎn)陣,這些值直接地或通過指針引用來指示存儲器塊尺寸的可能范圍。該點(diǎn)陣用來確定某些存儲器操作是否溢出可用的存儲。存儲器尺寸點(diǎn)陣24的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值;以及·兩個(gè)存儲器范圍點(diǎn)陣值的合并,其結(jié)果如下·范圍最大化←范圍1最大化 范圍2最大化( 算子的“最大值”)·范圍最小化←范圍1最小化 范圍2最小化( 算子的“最小值”)例如,用C或C++聲明的數(shù)組char a[100]具有100字節(jié)尺寸,是一個(gè)條目(1字節(jié))乘以數(shù)組中元素的數(shù)量(100)的尺寸。
作為另一示例,表示尺寸值范圍的存儲器尺寸點(diǎn)陣是有用的char a[100]char b[200]char*c=(i==0)?ab;在該情形中,取決于選擇數(shù)組a還是數(shù)組b,由變量c所指向的存儲器塊的尺寸可以是100字節(jié)或者200字節(jié),而這種選擇又取決于另一個(gè)變量i是否是0。用于該變量的存儲器尺寸點(diǎn)陣結(jié)果可指定尺寸的最大值為200字節(jié),最小值為100字節(jié)。
圖4示出了數(shù)據(jù)尺寸點(diǎn)陣26的示例。數(shù)據(jù)尺寸點(diǎn)陣直接地或通過指針引用來指示在存儲器塊內(nèi)已知數(shù)據(jù)尺寸的可能范圍。該點(diǎn)陣用作確定某些存儲器操作是否溢出可用的存儲器。特別地,它通常用來指示無效終止字符串的尺寸,該無效終字符串尺寸可比包含其的存儲器塊要小。數(shù)據(jù)尺寸點(diǎn)陣26的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值;·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值;以及·兩個(gè)存儲器范圍點(diǎn)陣值的合并,其結(jié)果如下·范圍最大化←范圍1最大化 范圍2最大化·范圍最小化←范圍1最小化 范圍2最小化圖5示出無效終止點(diǎn)陣28的示例。無效終止點(diǎn)陣指示是否已知數(shù)據(jù)要被無效終止,例如,具有作為最終條目的指示數(shù)據(jù)結(jié)束的值0。它通常結(jié)合字符串結(jié)構(gòu)使用。數(shù)據(jù)的范圍包括指定它是無效終止的還是非無效終止的。無效終止點(diǎn)陣的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值;·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值·兩個(gè)相等的非高、非低點(diǎn)陣值的合并,其結(jié)果是相同的點(diǎn)陣值;以及·兩個(gè)不同的非高、非低點(diǎn)陣值的合并,其結(jié)果是低點(diǎn)陣值()。
圖6示出存儲器位置點(diǎn)陣30的示例。存儲器位置點(diǎn)陣指示包含存儲器塊的存儲器種類,例如,堆棧存儲器、堆陣存儲器、靜態(tài)存儲器、和常量存儲器。也可指定其它種類的存儲器。存儲器位置點(diǎn)陣30的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值;·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值;·兩個(gè)相等的非高、非低點(diǎn)陣值的合并,其結(jié)果是相同的點(diǎn)陣值;以及·兩個(gè)不同的非高、非低點(diǎn)陣值的合并,其結(jié)果是低點(diǎn)陣值()。
圖7示出字符串值點(diǎn)陣32的示例。字符串值點(diǎn)陣指示存儲器塊的一個(gè)或多個(gè)常量字符串值。字符串值點(diǎn)陣的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值;·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值;·兩個(gè)相等的非高、非低常量字符串的合并,其結(jié)果是該常量字符串作為點(diǎn)陣值;以及·兩個(gè)不同的非高、非低常量字符串的合并,其結(jié)果是低點(diǎn)陣值()。
圖8示出數(shù)據(jù)源點(diǎn)陣34的示例。數(shù)據(jù)源點(diǎn)陣指示數(shù)據(jù)的源,例如,指定該數(shù)據(jù)是在內(nèi)部產(chǎn)生的(與所分析例程相關(guān))還是在外部產(chǎn)生的。未知源的數(shù)據(jù)具有低值。數(shù)據(jù)源點(diǎn)陣的合并規(guī)則如下·高值()和任何其它值的合并,其結(jié)果是其它值;·低值()和任何其它值的合并,其結(jié)果是一個(gè)低值;·兩個(gè)相等的非高、非低點(diǎn)陣值的合并,其結(jié)果是相同的點(diǎn)陣值;以及·兩個(gè)不同的非高、非低點(diǎn)陣值的合并,其結(jié)果是低點(diǎn)陣值()。
“弱點(diǎn)點(diǎn)陣”表示非整數(shù)類型變量(或表達(dá)式)的屬性。在較佳實(shí)施例中,它結(jié)合了存儲器尺寸點(diǎn)陣24、數(shù)據(jù)尺寸點(diǎn)陣26、無效終止點(diǎn)陣28、存儲器位置點(diǎn)陣30、字符串值點(diǎn)陣32、以及數(shù)據(jù)源點(diǎn)陣34。
圖9示出了在本發(fā)明較佳實(shí)施例的流非敏感分析14中執(zhí)行的各個(gè)步驟的流程圖。該流非敏感分析14導(dǎo)出每個(gè)非整數(shù)類型變量或表達(dá)式的弱點(diǎn)點(diǎn)陣以及每個(gè)整數(shù)類型變量或表達(dá)式的整數(shù)點(diǎn)陣。此處所用術(shù)語表達(dá)式點(diǎn)陣,是指在非整數(shù)變量或表達(dá)式情形下的弱點(diǎn)點(diǎn)陣,以及在整數(shù)類型變量和表達(dá)式情形下的整數(shù)點(diǎn)陣。
該流始于初始測試36,以確定所分析的變量是否為數(shù)組或結(jié)構(gòu)。如果是,則該變量與弱點(diǎn)點(diǎn)陣相關(guān)聯(lián)。然后在步驟38做出測試以確定該變量是否對其它例程可見或者作為一自變量傳遞到其它例程中。
如果該變量對其它例程可見或者作為一自變量傳遞到其它例程中,則在步驟40設(shè)置該變量的弱點(diǎn)點(diǎn)陣,以指定具有設(shè)置為該變量尺寸的值的存儲器尺寸點(diǎn)陣。在步驟40中將該弱點(diǎn)點(diǎn)陣的所有其它值設(shè)置為低。雖然未在本流程圖中示出,但如果該變量是一常量初始化變量,則數(shù)據(jù)尺寸點(diǎn)陣、無效終止點(diǎn)陣、以及字符串值點(diǎn)陣被設(shè)置為指示該變量的初始化值。
如果該變量對其它例程不可見或沒有作為自變量傳遞到其它例程中,則存儲器尺寸點(diǎn)陣被設(shè)置為變量尺寸的值。在步驟42中該弱點(diǎn)點(diǎn)陣中的所有其它值被設(shè)置為高。
如果步驟36的結(jié)果為“假”(表示變量不是數(shù)組或結(jié)構(gòu)),則流程進(jìn)入步驟44。在步驟44中,執(zhí)行一檢測以確定所分析的變量是否是一指針。如果是,則邏輯進(jìn)入步驟46以確定該指針變量是否對其它例程可見,或者它是否已作為自變量被傳遞到其它例程中。
如果該變量對其它例程可見或作為自變量傳遞到其它例程中,則在步驟49中,該指針變量與弱點(diǎn)點(diǎn)陣相關(guān)聯(lián),并且弱點(diǎn)點(diǎn)陣的所有值被設(shè)置為低。
如果該變量對其它例程不可見或沒有作為自變量傳遞到其它例程中,則在步驟48中,該指針變量與弱點(diǎn)點(diǎn)陣相關(guān)聯(lián),并且弱點(diǎn)點(diǎn)陣的所有值被設(shè)置為高。
如果步驟44的結(jié)果為“假”(表示變量不是數(shù)組、結(jié)構(gòu)或指針),則流程進(jìn)入步驟50。在步驟50中,執(zhí)行一檢測以確定所分析的變量是否是一個(gè)整數(shù)類型變量。整數(shù)類型變量與整數(shù)類型點(diǎn)陣相關(guān)聯(lián)。如果是,邏輯進(jìn)入步驟52以確定整數(shù)變量是否對其它例程可見,或者它是否作為自變量被傳遞到其它例程中。
如果該變量對其它例程可見或已作為自變量傳遞到其它例程中,則在步驟56中,該整數(shù)類型變量與整數(shù)點(diǎn)陣相關(guān)聯(lián),其中所有值被設(shè)置為低。
如果該變量對其它例程不可見或沒有作為自變量傳遞到其它例程中,則在步驟54中,整數(shù)點(diǎn)陣中的值被設(shè)置為高。
在流非敏感分析14導(dǎo)出例程中每個(gè)變量的弱點(diǎn)點(diǎn)陣或者整數(shù)點(diǎn)陣之后,流非敏感分析14訪問例程中的每一語句。該訪問可以任何順序進(jìn)行。語句中的每個(gè)表達(dá)式都以該順序被訪問,從而在處理該表達(dá)式之前,已處理所有作為輸入(即從屬性)的所有表達(dá)式。例如,在表達(dá)式中a=(b+c)+d;其部分、或者子表達(dá)式b或c必須在處理表達(dá)式(b+c)之前處理。類似地,子表達(dá)式(b+c)和d必須在處理表達(dá)式(b+c)+d之前處理。
圖10A-B示出用于處理例程中每個(gè)表達(dá)式的較佳實(shí)施例的流非敏感分析邏輯的流程圖。該流程始于初始化測試58,來確定所分析的表達(dá)式是否是用于變量的地址。如果是,則在步驟60中,進(jìn)行一測試以確定該變量是否是數(shù)組或結(jié)構(gòu)、或確定該變量是否是一常量字符串。如果是,則在步驟64中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián),其存儲器尺寸點(diǎn)陣被設(shè)置為變量尺寸,并且其存儲器位置點(diǎn)陣被設(shè)置為所引用變量的存儲器種類。如果該變量具有常量(const)屬性并且是字符串,則數(shù)據(jù)尺寸點(diǎn)陣被設(shè)置為字符串尺寸,并且無效終止點(diǎn)陣被設(shè)置為無效終止。字符串值點(diǎn)陣被設(shè)置為字符串值。數(shù)據(jù)源點(diǎn)陣被設(shè)置成指定數(shù)據(jù)源是內(nèi)部的。如果表達(dá)式指向變量地址、但該變量并非常量字符串,則在步驟62中,弱點(diǎn)點(diǎn)陣與表達(dá)式相關(guān)聯(lián),其存儲尺寸點(diǎn)陣設(shè)置為變量尺寸,且其存儲器位置點(diǎn)陣設(shè)置為所引用變量的存儲器種類。其它點(diǎn)陣條目被設(shè)置為低值。此外,由于該變量是地址明示的(即,指向它的指針存在、并且它可由寫入該指針的任何指針修改),所以在步驟62中,取得地址的弱點(diǎn)點(diǎn)陣使數(shù)據(jù)尺寸點(diǎn)陣、無效終止點(diǎn)陣、字符串值點(diǎn)陣、以及數(shù)據(jù)源點(diǎn)陣設(shè)置為低(其中存儲器尺寸點(diǎn)陣和存儲器位置點(diǎn)陣保持不變)。
如果步驟58的結(jié)果是“假”(表示表達(dá)式不指向變量地址),則流程進(jìn)入步驟66。在步驟66中,進(jìn)行一測試以確定該表達(dá)式是否用作變量值。如果是,則在步驟68中,該弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且所有的點(diǎn)陣條目被設(shè)置為低。
如果步驟66的結(jié)果是“假”(表示表達(dá)式不指向變量的地址或值),則流程進(jìn)入步驟70。在步驟70中,進(jìn)行一測試以確定該表達(dá)式是否用作常量字符串。如果是,則在步驟72中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且其存儲器尺寸點(diǎn)陣被設(shè)置成包括無效終止字節(jié)的常量字符串的尺寸;其數(shù)據(jù)尺寸點(diǎn)陣被設(shè)置成包括無效終止字節(jié)的常量字符串的尺寸;其無效終止點(diǎn)陣被設(shè)置成指示它是無效終止的;其存儲器位置點(diǎn)陣被設(shè)置成指示常量存儲器;其字符串值點(diǎn)陣被設(shè)置為字符串的內(nèi)容;以及其數(shù)據(jù)源點(diǎn)陣被設(shè)置為內(nèi)部的。
如果步驟70的結(jié)果是“假”(表示表達(dá)式不指向變量的地址或值、也不指向常量字符串),則流程進(jìn)入步驟74。在步驟74中,進(jìn)行一測試以確定該表達(dá)式是否用作整數(shù)常量(即整數(shù))。如果是,則在步驟76中,整數(shù)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián),且其值被設(shè)置為整數(shù)值。
如果步驟74的結(jié)果是“假”(表示表達(dá)式不指向變量的地址或值、也不指向常量字符串或整數(shù)常量),則流程進(jìn)入78。在步驟78中,進(jìn)行一測試以確定該表達(dá)式是否是“問號/冒號運(yùn)算”。問號/冒號運(yùn)算的通常形式是<表達(dá)式1>?<表達(dá)式2><表達(dá)式3>。如果是,則在步驟80中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且其點(diǎn)陣條目被設(shè)置為合并弱點(diǎn)點(diǎn)陣<表達(dá)式2>和<表達(dá)式3>(已預(yù)先設(shè)置)而得到的結(jié)果。
如果步驟78的結(jié)果是“假”,則流程進(jìn)入步驟82。在步驟82中,進(jìn)行一測試以確定該表達(dá)式是否是賦值運(yùn)算,即將該表達(dá)式賦給變量。如果是,則在步驟84中,更新目標(biāo)(即被賦值的)變量的表達(dá)式點(diǎn)陣。具體地,表達(dá)式點(diǎn)陣的先前各值與賦給目標(biāo)變量的表達(dá)式的表達(dá)式點(diǎn)陣合并。
如果步驟82的結(jié)果是“假”,則流程進(jìn)入步驟86。在步驟86中,進(jìn)行一測試以確定該表達(dá)式是否用于整數(shù)運(yùn)算。如果是,則在步驟88中,該運(yùn)算的每個(gè)輸入的整數(shù)值點(diǎn)陣被用來計(jì)算結(jié)果整數(shù)點(diǎn)陣和該表達(dá)式的值。
如果步驟86的結(jié)果是“假”,則流程進(jìn)入步驟90。在步驟90中,進(jìn)行一測試以確定該表達(dá)式是否用于“尺寸”運(yùn)算,即形式為尺寸(size of)(<變量或類型>)。如果是,則在步驟92中,整數(shù)點(diǎn)陣與表達(dá)式相關(guān)聯(lián),且其值是變量(或類型)的尺寸。
如果步驟58、66、70、74、78、82、86和90的測試都為假,則在步驟94進(jìn)行默認(rèn)賦值,其中表達(dá)式點(diǎn)陣的所有值都被設(shè)置為低。
以下示例是要通過流非敏感分析邏輯分析以確定緩沖流弱點(diǎn)是否存在的示例性代碼分段。每一個(gè)代碼分段后面都有流非敏感分析邏輯如何用上述各種點(diǎn)陣來對變量和表達(dá)式建模的描述。
示例1void testl(int i){char buf[100];char*p;switch(i){case 1p=“1”;break;case 2p=“12”;breakdefaultp=“123”;break;}strcpy(buf,p);}void testl(int i){創(chuàng)建了變量i的整數(shù)點(diǎn)陣,因?yàn)樗宦暶鳛椤癷nt”類型、且其整數(shù)點(diǎn)陣值設(shè)置為低←char buf[100];弱點(diǎn)點(diǎn)陣與變量“buf”相關(guān)聯(lián),并且因?yàn)樗且粋€(gè)數(shù)組,所以其存儲器尺寸點(diǎn)陣被設(shè)置為結(jié)構(gòu)的尺寸buf←100。由于該變量是局部的,并且對其它例程不可見或者沒有作為自變量傳遞,所有其它的點(diǎn)陣都被設(shè)置為高←,參見圖9的步驟42。
char*p;弱點(diǎn)點(diǎn)陣與變量p相關(guān)聯(lián)。因?yàn)樗且粋€(gè)指針并且對其它例程不可見或者沒有作為自變量傳遞,所以所有的點(diǎn)陣都設(shè)置為高←,參見圖9的步驟48。
Switch(i){“i”的整數(shù)點(diǎn)陣具有值,參見以上內(nèi)容。
case 1p=“1”;這是一個(gè)賦值運(yùn)算,因而將會觸發(fā)圖10A-B的步驟82和84。結(jié)果,所賦值的變量的表達(dá)式點(diǎn)陣是變量點(diǎn)陣的先前值(在該情形中為高)與賦值給該變量的表達(dá)式的表達(dá)式點(diǎn)陣(在該情形中表達(dá)式是“1”)的合并結(jié)果。表達(dá)式“1”具有點(diǎn)陣存儲器尺寸點(diǎn)陣←2數(shù)據(jù)尺寸點(diǎn)陣←2無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←“1”合并規(guī)則的結(jié)果用于p的弱點(diǎn)點(diǎn)陣,并如下存儲器尺寸點(diǎn)陣←2數(shù)據(jù)尺寸點(diǎn)陣←2無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←“1”break;case2p=“12”;這也是一個(gè)賦值操作,因而觸發(fā)圖10A-B的步驟82和84的邏輯。結(jié)果,所賦值的變量的表達(dá)式點(diǎn)陣是變量點(diǎn)陣的先前值(見上面)與賦值給該變量的表達(dá)式的表達(dá)式點(diǎn)陣(在該情形中表達(dá)式是“12”)的合并結(jié)果。表達(dá)式“12”具有點(diǎn)陣存儲器尺寸點(diǎn)陣←3數(shù)據(jù)尺寸點(diǎn)陣←3無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←“12”合并規(guī)則的結(jié)果用于p的弱點(diǎn)點(diǎn)陣,并如下存儲器尺寸點(diǎn)陣←2到3的范圍數(shù)據(jù)尺寸點(diǎn)陣←2到3的范圍無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←break;defaultp=“123”;這還是一個(gè)賦值運(yùn)算,因而觸發(fā)圖10A-B的步驟82和84的邏輯。結(jié)果,所賦值的變量的表達(dá)式點(diǎn)陣是變量點(diǎn)陣的先前值與賦值給該變量的表達(dá)式的表達(dá)式點(diǎn)陣(在該情形中表達(dá)式是“123”)的合并結(jié)果。表達(dá)式“123”具有點(diǎn)陣存儲器尺寸點(diǎn)陣←4數(shù)據(jù)尺寸點(diǎn)陣←4無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←“123”合并規(guī)則的結(jié)果用于p的弱點(diǎn)點(diǎn)陣,并如下存儲器尺寸點(diǎn)陣←2到4的范圍數(shù)據(jù)尺寸點(diǎn)陣←2到4的范圍無效終止點(diǎn)陣←無效終止存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的字符串值點(diǎn)陣←break;}strcpy(buf,p);由于buf的地址被隱含地用作自變量,所以步驟62的邏輯被觸發(fā)、并且buf的弱點(diǎn)點(diǎn)陣被修改以將數(shù)據(jù)尺寸點(diǎn)陣、存儲器尺寸點(diǎn)陣、字符串值點(diǎn)陣和數(shù)據(jù)源點(diǎn)陣設(shè)置為未知。
由于表達(dá)式p指向變量的值,所以步驟68的邏輯被觸發(fā),并且表達(dá)式p的弱點(diǎn)點(diǎn)陣中的所有值被設(shè)置為未知。
示例2
static char y[100];void test2(char*z){strcpy(y,z);}static char y[100];弱點(diǎn)點(diǎn)陣與數(shù)組y相關(guān)聯(lián)。其存儲器尺寸設(shè)置為100,其存儲器種類點(diǎn)陣設(shè)置為靜態(tài),并且所有其它點(diǎn)陣設(shè)置為低←。
這樣做是因?yàn)樽兞縴對其它例程可見,參見圖9的步驟40。
void test2(char*z){弱點(diǎn)點(diǎn)陣與指針變量z相關(guān)聯(lián)。所有點(diǎn)陣設(shè)置為低←。這樣做是因?yàn)樽兞縵作為自變量傳遞到其它例程中,參見圖9的步驟49。
strcpy(y,z);由于y的地址被隱含地用作自變量,所以步驟62的邏輯被觸發(fā),并且y的弱點(diǎn)點(diǎn)陣被修改以將數(shù)據(jù)尺寸點(diǎn)陣、存儲器尺寸點(diǎn)陣、字符串值點(diǎn)陣和數(shù)據(jù)源點(diǎn)陣設(shè)置為未知。
由于表達(dá)式z指向變量的值,所以步驟68的邏輯被觸發(fā),并且表達(dá)式z的弱點(diǎn)點(diǎn)陣中的所有值被設(shè)置為未知。
在執(zhí)行流非敏感分析之后,調(diào)用點(diǎn)分析邏輯16被調(diào)用。調(diào)用點(diǎn)分析16導(dǎo)出在所分析例程內(nèi)調(diào)用點(diǎn)上傳遞的每個(gè)變量或表達(dá)式自變量的弱點(diǎn)點(diǎn)陣(“調(diào)用點(diǎn)”是在代碼內(nèi)調(diào)用例程的位置)。自變量可以是變量或者表達(dá)式。在較佳實(shí)施例中,調(diào)用點(diǎn)分析僅限于對選擇例程、過程、或者函數(shù)的調(diào)用,因?yàn)椴⒎撬械睦潭紩斐扇觞c(diǎn)風(fēng)險(xiǎn)。
在較佳實(shí)施例中,調(diào)用點(diǎn)分析16要求每個(gè)調(diào)用點(diǎn)都必須訪問;但是,無需以任何特定的順序進(jìn)行。調(diào)用的每個(gè)自變量都要分析,從而首先處理任何子表達(dá)式的相關(guān)性;即,例如,在處理構(gòu)成自變量的表達(dá)式之前,要處理作為該表達(dá)式輸入的所有子表達(dá)式。
調(diào)用點(diǎn)分析邏輯類似于流非敏感分析邏輯。但是,與流非敏感分析邏輯不同的是,在調(diào)用點(diǎn)分析邏輯中,引用變量值的任何表達(dá)式使該變量的弱點(diǎn)點(diǎn)陣與做出該引用的表達(dá)式相關(guān)聯(lián)。此外,對變量的任何賦值運(yùn)算不改變該變量的弱點(diǎn)點(diǎn)陣。
圖11A-B示出在調(diào)用點(diǎn)分析16中表達(dá)式分析所執(zhí)行的各個(gè)步驟的流程圖。該流程始于初始化測試96,以確定所分析的表達(dá)式是否用作變量地址。如果是,則在步驟98中,進(jìn)行一測試以確定該變量是否是數(shù)組或結(jié)構(gòu),或者確定該變量是否是一常量字符串。如果是,則在步驟102中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián),其存儲器尺寸點(diǎn)陣被設(shè)置為變量尺寸,并且其存儲器位置點(diǎn)陣被設(shè)置為所引用變量的存儲器種類。如果該變量具有常量(const)屬性并且是字符串,則數(shù)據(jù)尺寸點(diǎn)陣被設(shè)置為字符串尺寸、且無效終止點(diǎn)陣被設(shè)置為無效終止。字符串值點(diǎn)陣被設(shè)置為字符串值。數(shù)據(jù)源點(diǎn)陣被設(shè)置以指定數(shù)據(jù)源是內(nèi)部的。如果表達(dá)式指向變量的地址、但該變量并非常量字符串,則在步驟100中,弱點(diǎn)點(diǎn)陣與表達(dá)式相關(guān)聯(lián),其存儲器尺寸點(diǎn)陣設(shè)置為變量尺寸,且其存儲器位置點(diǎn)陣被設(shè)置為所引用變量的存儲器種類。其它點(diǎn)陣條目被設(shè)置為低值。
如果步驟96的結(jié)果是“假”,則流程進(jìn)入步驟104。在步驟104中,進(jìn)行一測試以確定該表達(dá)式是否用作變量值。如果是,則在步驟106中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且所有的點(diǎn)陣條目被設(shè)置為與該變量相關(guān)聯(lián)的點(diǎn)陣值。
如果步驟104的結(jié)果是“假”,則流程進(jìn)入步驟108。在步驟108中,進(jìn)行一測試以確定該表達(dá)式是否用作常量字符串。如果是,則在步驟110中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且所有存儲器尺寸點(diǎn)陣設(shè)置為包括無效終止字節(jié)的常量字符串尺寸;其數(shù)據(jù)尺寸點(diǎn)陣設(shè)置為包括無效終止字節(jié)的常量字符串尺寸;其無效終止點(diǎn)陣設(shè)置為指示它是無效終止的;其存儲器位置點(diǎn)陣設(shè)置為指示常量存儲器;其字符串值點(diǎn)陣設(shè)置為字符串的內(nèi)容;以及其數(shù)據(jù)源點(diǎn)陣設(shè)置為內(nèi)部的。
如果步驟108的結(jié)果是“假”,則流程進(jìn)入步驟112。在步驟112中,進(jìn)行一測試以確定該表達(dá)式是否用作整數(shù)常量(即整數(shù))。如果是,則在步驟114中,整數(shù)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián),并且其值設(shè)置為整數(shù)值。
如果步驟112的結(jié)果是“假”,則流程進(jìn)入116。在步驟116中,進(jìn)行一測試以確定該表達(dá)式是否是“問號/冒號運(yùn)算”。如果是,則在步驟118中,弱點(diǎn)點(diǎn)陣與該表達(dá)式相關(guān)聯(lián)、且其點(diǎn)陣條目被設(shè)置為合并弱點(diǎn)點(diǎn)陣<表達(dá)式2>和<表達(dá)式3>(已預(yù)先設(shè)置)而得到的結(jié)果。
如果步驟116的結(jié)果是“假”,則流程進(jìn)入步驟120。在步驟120中,進(jìn)行一測試以確定該表達(dá)式是否是賦值運(yùn)算,即將該表達(dá)式賦值給變量。如果是,則在步驟122中目標(biāo)(即被賦值的)變量的表達(dá)式點(diǎn)陣與該變量的先前表達(dá)式點(diǎn)陣保持相同。
如果步驟120的結(jié)果是“假”,則流程進(jìn)入步驟124,在步驟124中,進(jìn)行一測試以確定該表達(dá)式是否用于整數(shù)運(yùn)算。如果是,則在步驟126中該運(yùn)算的每個(gè)輸入的整數(shù)值點(diǎn)陣被用來計(jì)算結(jié)果整數(shù)點(diǎn)陣和該表達(dá)式的值。
如果步驟124的結(jié)果是“假”,則流程進(jìn)入步驟128。在步驟128中,進(jìn)行一測試以確定該表達(dá)式是否用于“尺寸”運(yùn)算。如果是,則在步驟130中,整數(shù)點(diǎn)陣與表達(dá)式相關(guān)聯(lián)、且其值是變量(或類型)的尺寸。
如果步驟96、104、108、112、116、120、124和128是假,則在步驟94中,進(jìn)行默認(rèn)賦值,其中所有表達(dá)式點(diǎn)陣的值都被設(shè)置為低。
回顧結(jié)合流非敏感分析邏輯而分析的示例性代碼分段,發(fā)生如下處理。
示例1void test1(int i){char buf[100];char*p;switch(i){case 1p=“1”;break;case 2p=“12”;breakdefaultp=“123”;break;}strcpy(buf,p);}對strcpy的調(diào)用使其自變量為點(diǎn)陣值進(jìn)行分析。自變量1具有值buf,它具有如下的弱點(diǎn)點(diǎn)陣值存儲器尺寸點(diǎn)陣←100數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←堆棧存儲器數(shù)據(jù)源點(diǎn)陣←自變量2具有值p,它具有如下的弱點(diǎn)點(diǎn)陣值存儲器尺寸點(diǎn)陣←2到4的范圍數(shù)據(jù)尺寸點(diǎn)陣←2到4的范圍無效終止點(diǎn)陣←無效終止字符串值點(diǎn)陣←
存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的}示例2static char y[100];void test2(char*z){strcpy(y,z);}對strcpy的調(diào)用使其自變量為點(diǎn)陣值進(jìn)行分析。自變量1具有值y,它具有如下的弱點(diǎn)點(diǎn)陣值存儲器尺寸點(diǎn)陣←100數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←堆棧存儲器數(shù)據(jù)源點(diǎn)陣←自變量2具有值z,它具有如下的弱點(diǎn)點(diǎn)陣值存儲器尺寸點(diǎn)陣←數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←數(shù)據(jù)源點(diǎn)陣←}根據(jù)本發(fā)明一實(shí)施例,創(chuàng)建了庫調(diào)用點(diǎn)的那些自變量的弱點(diǎn)點(diǎn)陣,這些庫調(diào)用點(diǎn)是已經(jīng)知道具有潛在弱點(diǎn)的??稍跀?shù)據(jù)庫20中標(biāo)識庫調(diào)用點(diǎn)。
選擇調(diào)用點(diǎn)中弱點(diǎn)點(diǎn)陣的語言無關(guān)分析一旦自變量的弱點(diǎn)點(diǎn)陣被創(chuàng)建來選擇例程調(diào)用,就會再以一種語言無關(guān)方式來分析源代碼,以確定源代碼是否具有應(yīng)該已指出的弱點(diǎn)。本發(fā)明的較佳實(shí)施例操作用弱點(diǎn)數(shù)據(jù)庫20的弱點(diǎn)評估邏輯18,來執(zhí)行該分析。
弱點(diǎn)數(shù)據(jù)庫20是包含有關(guān)多個(gè)預(yù)識別例程的信息的數(shù)據(jù)庫。在其中它指定可導(dǎo)致弱點(diǎn)的條件。這些條件被指定為對傳遞給例程的自變量的弱點(diǎn)點(diǎn)陣的限制。
弱點(diǎn)評估邏輯18操作如下。檢查源代碼中由調(diào)用點(diǎn)分析16分析的每個(gè)調(diào)用點(diǎn),但無需以任何特定順序進(jìn)行。這些所調(diào)用例程的名稱,以及可能有關(guān)其自變量類型的信息,被用來創(chuàng)建例程查找名稱。該例程查找名稱在弱點(diǎn)數(shù)據(jù)庫20中用作關(guān)鍵值,以發(fā)現(xiàn)該調(diào)用點(diǎn)是否可能是易損的。
如果該查找未能發(fā)現(xiàn)相應(yīng)的條目,則調(diào)用點(diǎn)被確定為不易受損,因?yàn)樵摾堂Q沒有數(shù)據(jù)庫20中所指定的已知弱點(diǎn)。
如果該查找發(fā)現(xiàn)了一個(gè)相應(yīng)條目,則檢查該條目,以找出用作是評估特定調(diào)用的規(guī)則的匹配行動列表。這些匹配行動以特定順序提供。每個(gè)匹配行動與每個(gè)自變量的弱點(diǎn)點(diǎn)陣作比較,以確定來自自變量的弱點(diǎn)點(diǎn)陣是否與匹配行動的要求相匹配。如下述示例所示,如果匹配發(fā)生,則該行動報(bào)告所檢查調(diào)用點(diǎn)的弱點(diǎn)。然后該報(bào)告可由開發(fā)人員用來確定潛在弱點(diǎn)。對一個(gè)特定的調(diào)用點(diǎn)可檢測出多個(gè)弱點(diǎn)。
回顧結(jié)合語言特定處理邏輯而分析的示例性代碼分段,在弱點(diǎn)評估中進(jìn)行如下處理示例1這是具有如下語言特定代碼的示例strcpy(buf,p);該調(diào)用的調(diào)用點(diǎn)分析產(chǎn)生第一自變量buf的下述弱點(diǎn)點(diǎn)陣存儲器尺寸點(diǎn)陣←100數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←堆棧存儲器數(shù)據(jù)源點(diǎn)陣←該調(diào)用點(diǎn)分析還產(chǎn)生第二自變量p的以下弱點(diǎn)分析存儲器尺寸點(diǎn)陣←2到4的范圍數(shù)據(jù)尺寸點(diǎn)陣←2到4的范圍無效終止點(diǎn)陣←無效終止字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←常量存儲器數(shù)據(jù)源點(diǎn)陣←內(nèi)部的從數(shù)據(jù)庫20中返回的匹配行動指定要應(yīng)用于評估對例程strcpy()的調(diào)用的弱點(diǎn)點(diǎn)陣的某些規(guī)則。在調(diào)用strcpy()的特定情形中,這些規(guī)則檢查第一自變量具有大于或等于第二自變量最大數(shù)據(jù)尺寸的最小存儲尺寸。這樣,這些規(guī)則(匹配行動)確定該特定調(diào)用是否產(chǎn)生了緩沖溢出的風(fēng)險(xiǎn)。在該情形下,假設(shè)涉及了源代碼的有效語義分析,則不可能有溢出。
自變量1(100)的最小存儲器尺寸大于或等于自變量2(4)的最大數(shù)據(jù)尺寸,因此緩沖不可能溢出。自變量2的數(shù)據(jù)源是內(nèi)部的,因此它不可能是一個(gè)弱點(diǎn)。該調(diào)用不會被標(biāo)記為弱點(diǎn)。
示例2這是具有下述語言特定代碼的示例strcpy(y,z);該調(diào)用的調(diào)用點(diǎn)分析產(chǎn)生第一自變量y的下述弱點(diǎn)點(diǎn)陣存儲器尺寸點(diǎn)陣←100數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←堆棧存儲器數(shù)據(jù)源點(diǎn)陣←該調(diào)用點(diǎn)分析還產(chǎn)生第二自變量z的下述弱點(diǎn)分析存儲器尺寸點(diǎn)陣←數(shù)據(jù)尺寸點(diǎn)陣←無效終止點(diǎn)陣←字符串值點(diǎn)陣←存儲器位置點(diǎn)陣←數(shù)據(jù)源點(diǎn)陣←從數(shù)據(jù)庫20中返回的匹配行動指定要應(yīng)用于評估對例程strcpy()的調(diào)用的弱點(diǎn)點(diǎn)陣的某些規(guī)則。在調(diào)用strcpy()的特定情形中,這些規(guī)則檢查第二自變量的最大數(shù)據(jù)尺寸為,因而未知。因此,有緩沖溢出的可能性。類似地,第二自變量的數(shù)據(jù)源為,因而未知。因此,有再次出現(xiàn)弱點(diǎn)的可能性。(如果輸入是未知的或者是外部的,就有出現(xiàn)尺寸太小、或輸入并非來自于內(nèi)部源的可能性,這將產(chǎn)生弱點(diǎn)。)在調(diào)用strcpy()的特定情形中自變量2的最大數(shù)據(jù)尺寸為,因此緩沖溢出。自變量2的數(shù)據(jù)源為,因此是一弱點(diǎn)。該調(diào)用被標(biāo)記為弱點(diǎn)。
上述的實(shí)施例涉及檢測緩沖溢出弱點(diǎn)的方法。如上所述,該方法可用于檢測其它諸如紊亂情況和特許升級的弱點(diǎn)。
紊亂情況在此所用的術(shù)語“紊亂情況”是指在一個(gè)程序中相繼發(fā)生一對例程調(diào)用,并且如果不能原子地執(zhí)行(即,不被機(jī)器上的其它線程和進(jìn)程中斷),則可變成一個(gè)弱點(diǎn)。典型的示例是對確定文件訪問權(quán)的調(diào)用,以及對基于該訪問來讀或?qū)懺撐募暮罄m(xù)調(diào)用。如果該過程在兩個(gè)調(diào)用之間被中斷,并且其文件屬性在中斷期間被修改,則第二個(gè)調(diào)用可能讀取錯誤的信息或者寫入不當(dāng)文件。
以下是代碼分段要分析以確定是否有紊亂情況存在的示例性代碼分段。它使用access()和fopen()來示出可能易受損的一對相關(guān)調(diào)用。
示例3…部分代碼A…1)r=access(filename,…)…部分代碼B…2)if(r)then…部分代碼C…3)foppen(filename,…)…部分代碼D…在該示例中,有對特定文件名的access()調(diào)用,隨后是對來自access()的返回值的測試。如果測試?yán)^續(xù),則對同一文件名調(diào)用fopen()。占位符被列出,用于可能在已編號語句周圍出現(xiàn)的任意代碼。fopen()調(diào)用是從access()調(diào)用可及的;這就表示在兩個(gè)調(diào)用之間對該文件沒有其它操作,且如果測試?yán)^續(xù),fopen()將會緊隨access()。
盡管本示例將access()和fopen()的自變量示為單獨(dú)的變量名稱,但是自變量有可能是任意表達(dá)式,諸如文件名_列表[1](名稱數(shù)組中的一個(gè)條目),或者全路徑+基本長度(指向全路徑的字符串基本長度字符的指針)。重要的是該自變量的運(yùn)行時(shí)間值對于兩個(gè)調(diào)用是相同的。
如上述緩沖溢出條件的實(shí)施例中,詞匯分析器用來產(chǎn)生要分析代碼的紊亂情況的IR。在該實(shí)施例中,IR包括有關(guān)程序中聲明的信息,并且記錄與程序中識別符有關(guān)的諸如其類型的信息。它可以區(qū)分函數(shù)聲明和函數(shù)調(diào)用。
提供了控制流圖表,以示出基塊結(jié)構(gòu)以及在確定程序控制流的各塊之間的分支。在圖12中示出了控制流圖表的示例。矩形實(shí)體140是基塊(沒有分支的連續(xù)直線語句,表示“if”、“while”等);橢圓形142是內(nèi)部有任意控制流的代碼區(qū)域;以及箭頭144表示在基塊或代碼區(qū)域之間的控制流程。
使用控制流圖表,系統(tǒng)從包含open()調(diào)用的塊起反向遍歷之前的各個(gè)塊。在所示示例中,它去到包含access()調(diào)用的塊,并且作標(biāo)記access()調(diào)用在open()調(diào)用之前。知道了這些調(diào)用是相關(guān)的,它檢查每個(gè)調(diào)用的自變量列表,關(guān)注對應(yīng)于文件名的自變量。作為一種探索法,它比較相應(yīng)表達(dá)式的結(jié)構(gòu)。在該示例中,它會發(fā)現(xiàn)兩個(gè)表達(dá)式都是對同一變量的引用,并且它可得到結(jié)論兩個(gè)調(diào)用都是引用同一文件,結(jié)果將標(biāo)記一個(gè)紊亂情況弱點(diǎn)。
在用于檢測紊亂情況弱點(diǎn)的另一實(shí)施例中,可以結(jié)合上述系統(tǒng)使用數(shù)據(jù)流分析,以便提供與在程序中不同點(diǎn)的變量值有關(guān)的信息。例如,它可確定變量文件名在access()調(diào)用和fopen()調(diào)用中是否具有相同的值。數(shù)據(jù)流分析還可用來確定描述為全路徑+基本長度的access()的自變量是否具有與描述為文件名的fopen()的自變量的相同值。
特許升級當(dāng)具有高水平系統(tǒng)特許的應(yīng)用可用來執(zhí)行預(yù)期設(shè)計(jì)之外的動作時(shí),特許升級弱點(diǎn)就會產(chǎn)生,允許外部一方獲得否則不具備的對系統(tǒng)的特許訪問。
以下是用于特許升級檢測的示例性代碼分段。
示例4void somefunc(){…SetSecurityDescriptorDacl(&descriptor,TRUE,NULL/*ACL*/,F(xiàn)ALSE);}在本示例中,WindowsAPI調(diào)用設(shè)置資源的安全屬性。弱點(diǎn)在于資源的ACL(訪問控制列表)永遠(yuǎn)不能設(shè)置為空,因?yàn)檫@樣的話資源就可被未經(jīng)授權(quán)的用戶所訪問或修改。
在上述實(shí)施例中,語言解析器用來創(chuàng)建來自源代碼的IR。IR提供包括在文件中聲明的所有類型、常數(shù)、變量和函數(shù)的信息的符號表。函數(shù)‘somefunc’的信息包括對‘somefunc’語句的引用。IR的語句包括可應(yīng)用語言(C或C++中的“if”,“while”,“for”等)以及表達(dá)式(包括賦值、函數(shù)調(diào)用、算法運(yùn)算等)的控制流程語句。函數(shù)調(diào)用信息包括所調(diào)用例程的符號表格條目,以及對應(yīng)于自變量的表達(dá)式列表。提供了可能易損調(diào)用的數(shù)據(jù)庫。
IR被遍歷,其中每個(gè)函數(shù)定義及該定義內(nèi)的語句被訪問。在函數(shù)調(diào)用節(jié)點(diǎn)上調(diào)用的例程與數(shù)據(jù)庫信息相匹配。當(dāng)出現(xiàn)匹配時(shí),函數(shù)調(diào)用將進(jìn)行更詳細(xì)地查看。
使特定調(diào)用易損的特定條件已被預(yù)先確定。在上述示例中,已經(jīng)知道潛在的問題在于SetSecurityDescriptionDacl()的第三自變量不應(yīng)為NULL。在調(diào)用例程時(shí),該調(diào)用的IR應(yīng)指向SetSecurityDescriptorDacl,并且在自變量的表達(dá)式列表中應(yīng)該有四個(gè)條目。第一個(gè)條目是變量‘descriptor’的地址,其余三個(gè)是TRUE、NULL、和FALSE的IR常量。
找到與SetSecurityDescriptorDacl的匹配將觸發(fā)對該調(diào)用的自變量的進(jìn)一步檢查。在這種情形中,有關(guān)SetSecurityDescriptorDacl的潛在弱點(diǎn)的認(rèn)知將導(dǎo)致對第三自變量的檢查。IR將其直接描述為NULL,并且該調(diào)用點(diǎn)將被標(biāo)記為易損的。
如上所述,本發(fā)明的較佳實(shí)施例分析了源代碼本身的某些語義特征,以確定是否可能存在弱點(diǎn)。例如,根據(jù)有關(guān)例程的一些已知行為(例如,例程將一個(gè)自變量拷貝到由另一個(gè)自變量所指向的緩沖器),對例程的自變量進(jìn)行算法分析,以檢測有問題的調(diào)用。這種方法避免了在現(xiàn)有技術(shù)方法和提案中發(fā)現(xiàn)的許多假陽性。
到此為止,安全專家使用已知規(guī)則來分析代碼以查找弱點(diǎn),但是這是勞動強(qiáng)度大而且易出錯的。本發(fā)明最大化對諸如緩沖溢出、紊亂情況、以及特許升級的弱點(diǎn)的語義分析。它還提供了一個(gè)框架,從而當(dāng)發(fā)現(xiàn)其它弱點(diǎn)時(shí),用于檢測這些弱點(diǎn)的匹配行動可被指定并且結(jié)合到較佳系統(tǒng)中。
在上述實(shí)施例中,源代碼是(a)用在ANSI標(biāo)準(zhǔn)X3J11中所述的ANSI語言寫成的可執(zhí)行程序的部分或全部文本,并且具有常用擴(kuò)展,諸如由微軟和GNU編譯器所提供的擴(kuò)展,或者(b)用在ANSI標(biāo)準(zhǔn)X3J16中所描述的ANSI C++語言寫成的可執(zhí)行程序的部分或全部文本,并且具有常用擴(kuò)展,諸如由微軟和GNU編譯器提供的擴(kuò)展。然而,可以理解,本發(fā)明還可用來分析由其它語言寫成的源代碼。
雖然本發(fā)明結(jié)合某些較佳實(shí)施例得到了描述,但是可以理解,并非要將本發(fā)明限定在這些特殊的實(shí)施例中。相反地,旨在涵蓋所有可能包括在附加權(quán)利要求中的變化、修改和等效體。提出了一些特定數(shù)字和源代碼語言,但是可以理解,這些數(shù)字和源代碼語言僅僅是作為示例給出,并非以任何方式來限制本發(fā)明的范圍。
權(quán)利要求
1.一種檢測源代碼中弱點(diǎn)的方法,包括分析源代碼中的變量并從中創(chuàng)建模型,其中每個(gè)模型指定與每個(gè)變量有關(guān)的預(yù)定特征;使用所述變量模型創(chuàng)建所述源代碼中例程調(diào)用的自變量的模型;結(jié)合所述相應(yīng)例程調(diào)用的預(yù)定標(biāo)準(zhǔn)來使用所述自變量模型,以確定所述例程調(diào)用是否具備因所述自變量和已知例程行為引起的弱點(diǎn)。
2.如權(quán)利要求1所述的方法,其特征在于,所述模型指定變量的存儲器尺寸。
3.如權(quán)利要求1所述的方法,其特征在于,所述模型指定一變量的數(shù)據(jù)尺寸。
4.如權(quán)利要求1所述的方法,其特征在于,所述模型對字符串值類型的變量指定所述變量是無效終止字符串還是非無效終止字符串。
5.如權(quán)利要求1所述的方法,其特征在于,所述模型指定所述變量的存儲器類型。
6.如權(quán)利要求1所述的方法,其特征在于,所述模型對字符串值類型的變量指定字符串值。
7.如權(quán)利要求1所述的方法,其特征在于,所述模型對變量指定數(shù)據(jù)源。
8.如權(quán)利要求1所述的方法,其特征在于,所述自變量模型指定可變自變量的特征。
9.如權(quán)利要求1所述的方法,其特征在于,所述自變量模型指定表達(dá)式自變量的特征。
10.如權(quán)利要求1所述的方法,其特征在于,所述模型被指定為點(diǎn)陣。
11.如權(quán)利要求10所述的方法,其特征在于,所述點(diǎn)陣值包括表示不知道的值、表示不一致認(rèn)知的值、以及表示認(rèn)知的明確表達(dá)的值。
12.如權(quán)利要求11述的方法,其特征在于,表示認(rèn)知的明確表達(dá)的所述值包括指定特定值范圍的值。
13.如權(quán)利要求1所述的方法,其特征在于,相應(yīng)例程的所述預(yù)定標(biāo)準(zhǔn)包括與所述例程的語義行為有關(guān)的規(guī)則。
14.如權(quán)利要求1所述的方法,其特征在于,所述弱點(diǎn)是緩沖溢出。
15.一種檢測源代碼中弱點(diǎn)的方法,包括產(chǎn)生描述與例程的流有關(guān)的某些特征的模型;以及結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用所述模型,以確定所述例程調(diào)用是否具備因所述例程的流引起的弱點(diǎn)。
16.如權(quán)利要求15所述的方法,其特征在于,所述弱點(diǎn)是紊亂情況。
17.一種檢測源代碼中弱點(diǎn)的方法,包括產(chǎn)生描述與要在例程中執(zhí)行的行動有關(guān)的某些特征的模型;以及結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用所述模型,以確定所述例程調(diào)用是否具備弱點(diǎn),所述弱點(diǎn)可使例程中的行動可在所述預(yù)期設(shè)計(jì)之外執(zhí)行。
18.如權(quán)利要求17所述的方法,其特征在于,所述弱點(diǎn)是特許升級。
19.一種檢測源代碼中弱點(diǎn)的方法,包括分析源代碼以創(chuàng)建所述源代碼中例程調(diào)用的自變量的模型;以及結(jié)合相應(yīng)例程調(diào)用的預(yù)定標(biāo)準(zhǔn)使用所述模型,以確定所述例程調(diào)用是否具備因所述自變量和所述例程行為引起的弱點(diǎn)。
20.一種檢測源代碼中弱點(diǎn)的系統(tǒng),包括計(jì)算機(jī)實(shí)現(xiàn)邏輯,用于分析源代碼中的變量并從中創(chuàng)建模型,其中每個(gè)模型指定與每個(gè)變量有關(guān)的預(yù)定特征;計(jì)算機(jī)實(shí)現(xiàn)邏輯,用于使用所述變量模型來創(chuàng)建源代碼中例程調(diào)用的自變量的模型;以及計(jì)算機(jī)實(shí)現(xiàn)邏輯,結(jié)合相應(yīng)例程調(diào)用的預(yù)定標(biāo)準(zhǔn)使用所述自變量模型,以確定所述例程調(diào)用是否具備因所述自變量和已知例程行為引起的弱點(diǎn)。
21.如權(quán)利要求20所述的系統(tǒng),其特征在于,結(jié)合相應(yīng)例程調(diào)用的預(yù)定標(biāo)準(zhǔn)使用所述模型以確定所述例程調(diào)用是否具備因所述自變量和已知例程行為引起的弱點(diǎn)的計(jì)算機(jī)實(shí)現(xiàn)邏輯,包括一個(gè)基于對所述自變量模型的分析來指定檢測弱點(diǎn)的規(guī)則的數(shù)據(jù)庫。
22.一種用于檢測源代碼中弱點(diǎn)的系統(tǒng),包括計(jì)算機(jī)實(shí)現(xiàn)邏輯,用于產(chǎn)生描述與例程流的某些特征有關(guān)的模型;以及計(jì)算機(jī)實(shí)現(xiàn)邏輯,結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用所述模型,以確定所述例程調(diào)用是否具備因所述例程流引起的弱點(diǎn)。
23.一種用于檢測源代碼中弱點(diǎn)的系統(tǒng),包括計(jì)算機(jī)實(shí)現(xiàn)邏輯,用于產(chǎn)生描述與要在例程中執(zhí)行的行動的某些特征有關(guān)的模型;以及計(jì)算機(jī)實(shí)現(xiàn)邏輯,結(jié)合相應(yīng)例程的預(yù)定標(biāo)準(zhǔn)使用所述模型,以確定所述例程調(diào)用是否具備弱點(diǎn),所述弱點(diǎn)使例程中的行動可在所述預(yù)期設(shè)計(jì)之外執(zhí)行。
全文摘要
一種檢測源代碼中弱點(diǎn)的方法和系統(tǒng)。源代碼被解析為中間表達(dá)。(例如以點(diǎn)陣的形式)導(dǎo)出用于編碼中的變量、以及結(jié)合例程調(diào)用而使用的變量和/或表達(dá)式的模型。然后結(jié)合有關(guān)例程的預(yù)定規(guī)則來分析模型,以確定例程調(diào)用是否具備一個(gè)或多個(gè)預(yù)選弱點(diǎn)。
文檔編號H04L9/00GK1809812SQ200480017163
公開日2006年7月26日 申請日期2004年4月15日 優(yōu)先權(quán)日2003年4月18日
發(fā)明者R·J·伯格, L·羅斯, J·佩頓, J·J·達(dá)哈尼, R·格特里伯, C·瑞賓 申請人:盎司實(shí)驗(yàn)室股份有限公司