本發明屬于軟件測試和軟件可靠性領域,特別涉及一種多線程程序和協議中并發缺陷的檢測方法及系統。
背景技術:
1、隨著硬件技術的發展,cpu單核處理能力提升趨緩,多核技術快速發展成熟,并逐漸成為市場主流。在此背景下,為應對日趨復雜的應用需求,軟件領域加速并發化,通過多線程程序(采用多線程執行命令的用戶程序或運行多線程協議的系統程序,下文將它們簡稱為“多線程程序”)充分利用硬件資源,提升軟件性能。但多線程程序的廣泛應用帶來了新的安全問題。多線程程序中不同線程之間存在大量的共享資源,如果各個線程之間的同步操作出現錯誤,就會導致對共享資源的競爭,進而引發并發缺陷,導致數據錯誤、系統崩潰甚至惡意攻擊,帶來巨大的損失。更糟糕的是,多線程程序的調度情況存在不確定性,其調度空間存在爆炸問題,使得并發缺陷的檢測面臨巨大的挑戰。
2、常見的并發缺陷包括空指針解引用、指針未初始化使用、釋放后使用和二次釋放。空指針解引用并發缺陷是指在并發環境下,程序未能線程安全地檢查共享指針是否為空就對指針進行解引用操作。指針未初始化并發缺陷是指在并發環境下,程序未能線程安全地檢查共享指針是否已經被初始化就對指針進行解引用操作。釋放后使用并發缺陷是指在并發環境下,程序在訪問共享內存塊之前未能線程安全地檢查待訪問內存塊是否已經被其他線程釋放。二次釋放并發缺陷是指在并發環境下,程序在嘗試釋放一個共享內存塊之前未能線程安全地檢查待釋放內存塊是否已經被其他線程釋放。除以上四類并發缺陷外,還存在一些由于程序對并發共享變量的操作未實現線程安全導致的其他并發缺陷,包括數據競爭等。
3、針對以上并發缺陷,現有的檢測技術可以分為兩類:靜態檢測方法和動態檢測方法。前者在程序源代碼基礎上,利用數據流分析、符號執行、形式化驗證等技術檢測并發缺陷。后者則是利用程序的運行時信息進行檢測,按照采用的模型可以分為三類:基于鎖集的、運行時檢測分析以及基于偏序的。基于鎖集的技術將所有未使用相同互斥鎖保護的對同一共享變量的訪問視為并發缺陷。此技術會產生大量誤報。運行時檢測分析技術通過多次運行程序,窮盡合法的線程交錯來檢測缺陷。該類技術準確性高,但受狀態空間爆炸問題困擾。基于偏序的技術將程序的運行時信息收集成事件序列,記錄各線程的操作及操作發生順序,其中的每個操作被稱為一個事件。然后,基于內存讀/寫事件發生的順序關系、鎖申請/釋放事件發生的順序關系等信息在事件之間建立偏序關系,并將其中不存在偏序關系的兩個事件認為是可并發事件,而后通過閉包等算法對可并發事件進行進一步驗證。基于偏序的技術,其檢測效果和效率依賴于偏序模型以及可并發性驗證算法,在合理的模型基礎上可以保證結果的可靠性,而高效的可并發性驗證算法可以達到多項式時間復雜度。除以上檢測技術外,還存在針對特定并發缺陷的檢測技術,但其局限性較高,在大多數情況下難以擴展。
4、基于偏序的技術在效率和準確性方面都非常優秀,契合實際應用的需求,但存在漏報問題。其根本原因在于:該類技術是在已有事件序列的基礎上推斷其中部分事件的可并發性,由于控制流變換存在鏈式連鎖反應,因此為了保證結果的可靠性,現有偏序模型都要求推測出的事件序列與原有序列保持一致的控制流,進一步地,由于無法確定哪些事件會影響控制流,現有的偏序模型都采用一種強假設:任何讀寫事件出現順序的變化,即任何數據流的變化,都可能影響事件序列的控制流。這一假設嚴格限制了對可能的線程交錯順序的探索范圍,使得基于偏序的技術在進行并發缺陷檢測時只能在與輸入事件序列的線程交錯順序相臨近的空間進行探索。為了達到較高的檢測覆蓋率,該種檢測技術對輸入事件序列在線程交錯順序方面的多樣性有較高的要求。然而,大多數操作系統的并發調度策略完全固定,因此重復運行同一個多線程程序獲得的事件序列在線程交錯順序方面多樣性較低。由于這一瓶頸,基于偏序的技術很難達到較高的檢測覆蓋率,檢測效果受到了嚴重的限制。
技術實現思路
1、本發明的目的在于提供一種多線程程序和協議中并發缺陷的檢測方法及系統,能夠在保證結果的可靠性的前提下,允許推測出的事件序列與原有事件序列存在不同的指針數據流,從而放寬偏序關系的限制,在單次檢測過程中覆蓋更多的線程交錯順序的狀態,從而準確檢測出更多的并發缺陷。該方法不局限于某一種特定的并發缺陷,涵蓋空指針解引用、指針未初始化使用、釋放后使用和二次釋放以及由線程不安全性衍生出的多種并發缺陷。該方法可以在多項式時間內完成檢測,且保證結果的可靠性,即沒有誤報。
2、為簡化對本方法的陳述,引入以下符號表示與定義:
3、事件序列:以單個事件為元素,構成的順序序列;事件在事件序列中出現的先后順序代表事件發生的時間順序。
4、事件:使用符號e表示事件序列中的一個事件。
5、觀察數據依賴:在事件序列中,如果存在一個內存寫事件e1和一個內存讀事件e2,e2讀取的內存位置等于e1寫入的內存位置,且e2讀取到的值等于e1寫入的值,則稱在該事件序列中,e2觀察數據依賴于e1,標記為rf(e2)=e1。
6、為實現上述目標,本方法引入以下獨創概念:
7、前綴事件閉包:給定一個事件序列,和一個由該事件序列中的部分事件構成的集合s,稱滿足以下所有條件的最小事件集合為事件集合s的前綴事件閉包,并使用符號c(s)表示:(1)集合s是集合c(s)的子集;(2)對于c(s)中的任意事件e,對于所有在事件序列中早于e出現且與e處于同一線程下的事件e′,事件e′也在集合c(s)中;(3)對于c(s)中的任意內存讀事件e,若事件e存在觀察數據依賴rf(e)=ew,且為了維持控制流不變需要維持事件e的該觀察數據依賴,則事件ew也在集合c(s)中;(4)若c(s)中存在兩個不同的鎖申請事件ea1和ea2,且這兩個鎖申請事件嘗試申請同一個互斥鎖,則與其對應的兩個鎖釋放事件er1和er2也在集合c(s)中。
8、值數據依賴:在事件序列中,如果存在一個內存讀事件e1,和一個內存寫事件e2,e1讀取到的值在e2中被用作寫入內存的值,則稱e2值數據依賴于e1。
9、地址數據依賴:在事件序列中,如果存在一個內存讀事件e1,和一個類型為內存讀/寫或鎖申請/釋放類型的事件e2,e1讀取到的值在e2中被用作內存訪問操作地址的值,則稱e2地址數據依賴于e1。
10、數據通路:在事件序列中,若存在一系列事件e1,e2,e3,...,e2n,e2n+1,它們滿足:(1)對于任意下標為奇數的事件ei,i=2k+1,k為小于n的非負整數,ei+1觀察數據依賴于ei;(2)對于任意下標為偶數的事件ei,i=2k,k為小于等于n的正整數,ei+1值數據依賴于ei;(3)e2n+1地址數據依賴于e2n,則稱存在一條從e1到e2n+1的數據通路。
11、數據依賴圖:一張表示事件間的數據依賴關系的有向圖。給定一個事件序列,有向圖中的一個節點n(e)表示事件序列中的一個事件e,有向圖中的一條從n(e1)到n(e2)的有向邊表示存在e1到e2的數據通路。按照上述規則構建的有向圖稱為數據依賴圖。
12、共有數據依賴:給定一個事件序列及在其上構建的數據依賴圖,對于事件序列中的兩個不同事件e1和e2,若事件序列中存在另一個不同于e1和e2的事件e3,且數據依賴圖中同時存在e3到e1和e3到e2的有向通路,則稱e1和e2存在共有數據依賴。
13、在以上概念基礎上,本發明進一步采用以下技術方案:
14、一種多線程程序和協議中并發缺陷的檢測方法,包括:
15、生成待測目標程序的原始事件序列,所述待測目標程序為采用多線程執行命令的用戶程序或運行多線程協議的系統程序,所述原始事件序列中的原始事件包括:內存讀/寫事件、鎖申請/釋放事件、內存申請/釋放事件和分支事件;
16、移除所述原始事件序列中只涉及單線程獨占變量和只讀變量的事件,得到精簡事件序列;
17、基于所述精簡事件序列,構建數據依賴圖,并根據所述數據依賴圖中的通路信息,分析并還原出所述待測目標程序運行時的數據流動狀況,進而識別可能存在并發內存訪問行為的事件對;
18、根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列;
19、計算所述待驗證序列中所有事件的前綴事件閉包,并基于所述前綴事件閉包的事件集合和偏序集合構建一有向圖后,在所述有向圖基礎上求解偏序閉包,以得到并發缺陷檢測結果。
20、進一步地,基于所述精簡事件序列,構建數據依賴圖,包括:
21、對精簡事件序列中事件出現的先后次序以及所操作的內存對象進行分析,以提取一個包括觀察數據依賴、值數據依賴和地址數據依賴的數據依賴關系集合;其中,
22、所述觀察數據依賴是指在所述精簡事件序列中,如果存在一個內存讀事件e2讀取的內存位置等于一個內存寫事件e1寫入的內存位置,且該內存讀事件e2讀取到的值等于該內存寫事件e1寫入的值,則認為該內存讀事件e2觀察數據依賴于該內存寫事件e1;
23、所述值數據依賴是指在所述精簡事件序列中,如果存在一個內存讀事件e3讀取到的值在一個內存寫事件e4中被用作寫入內存的值,則認為該內存寫事件e4值數據依賴于該內存讀事件e3;在
24、所述地址數據依賴是指在所述精簡事件序列中,如果存在一個內存讀事件e5讀取到的值在一個類型為內存讀/寫或鎖申請/釋放類型的事件e6中被用作內存訪問操作地址的值,則認為該類型為內存讀/寫或鎖申請/釋放類型的事件e6地址數據依賴于該內存讀事件e5;
25、將所述精簡事件序列中的所有事件一一映射為數據依賴圖中的節點;
26、將所述數據依賴關系集合中的數據依賴關系一一映射為數據依賴圖中的有向邊,其中,所述有向邊終點所在的節點對有向邊起點所在節點存在觀察數據依賴、值數據依賴或地址數據依賴。
27、進一步地,根據所述數據依賴圖中的數據通路,分析并還原出所述待測目標程序運行時的數據流動狀況,進而識別可能存在并發內存訪問行為的事件對,包括:
28、確定所述數據依賴圖中的數據通路,其中,所述數據通路是指在所述數據依賴圖中存在一系列事件e1,e2,e3,...,e2n,e2n+1,且該系列事件e1,e2,e3,...,e2n,e2n+1滿足:
29、對于任意下標為奇數的事件ei,i=2k+1,k為小于n的非負整數,事件ei+1觀察數據依賴于事件ei;
30、和,
31、對于任意下標為偶數的事件ei,i=2k,k為小于等于n的正整數,事件ei+1值數據依賴于事件ei;
32、和,
33、e2n+1地址數據依賴于e2n;
34、根據所述數據依賴圖中的數據通路,確定存在共有數據依賴的事件對;其中,所述存在共有數據依賴的事件對是指如果所述數據依賴圖中存在一個事件e7,且該數據依賴圖中同時存在該事件e7到一事件e8和該事件e7到另一事件e9的數據通路,則該事件e8和事件e9為存在共有數據依賴的事件對;
35、將所述存在共有數據依賴的事件對認為是可能存在并發內存訪問行為的事件對。
36、進一步地,所述待測缺陷類型包括:空指針解引用;
37、所述根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列,包括:
38、在所述可能存在并發內存訪問行為的事件對中獲取由一個內存讀事件和一個內存寫事件構成的事件對;其中,所述內存讀事件向內存中寫入的值為零;
39、在所述精簡事件序列中獲取一個地址數據依賴于所述內存讀事件的事件;
40、按照內存寫事件、內存讀事件、地址數據依賴于所述內存讀事件的事件進行排序,以得到待驗證序列。
41、進一步地,所述待測缺陷類型包括:指針未初始化使用;
42、所述根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列,包括:
43、獲取一個內存讀事件以及所有與該內存讀事件可以組成所述可能存在并發內存訪問行為的事件對的內存寫事件;
44、按照內存讀事件、所有與該內存讀事件可以組成所述可能存在并發內存訪問行為的事件對的內存寫事件進行排序,以得到待驗證序列;其中,基于精簡事件序列中的事件順序,對所有與該內存讀事件可以組成所述可能存在并發內存訪問行為的事件對的內存寫事件進行排序。
45、進一步地,所述待測缺陷類型包括:釋放后重用;
46、所述根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列,包括:
47、在所述可能存在并發內存訪問行為的事件對中獲取由一個內存讀事件和一個內存釋放事件構成的事件對;
48、在所述精簡事件序列中獲取一個類型不為內存釋放且地址數據依賴于所述內存讀事件的事件;
49、按照內存釋放事件、內存讀事件、類型不為內存釋放且地址數據依賴于所述內存讀事件的事件進行排序,以得到待驗證序列。
50、進一步地,所述待測缺陷類型包括:二次釋放;
51、所述根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列,包括:
52、在所述可能存在并發內存訪問行為的事件對中獲取由一個內存讀事件和一個內存釋放事件構成的事件對;
53、在所述精簡事件序列中獲取一個地址數據依賴于所述內存讀事件的內存釋放事件;
54、按照內存釋放事件、內存讀事件、地址數據依賴于所述內存讀事件的內存釋放事件進行排序,以得到待驗證序列。
55、進一步地,計算所述待驗證序列中所有事件的前綴事件閉包,包括:
56、將待驗證序列中所有出現的事件加入前綴事件閉包;
57、重復應用事件擴充規則,對前綴事件閉包進行事件擴充,直至沒有新事件加入,其中,所述事件擴充規則包括:
58、對于前綴事件閉包中的任意事件e,將所有在精簡事件序列中早于事件e出現且與事件e處于同一線程下的事件e′加入到前綴事件閉包中;
59、對于前綴事件閉包中的任意內存讀事件e,若該內存讀事件e觀察數據依賴于一事件ew,且該事件ew用于維持控制流不變,則將該事件ew加入到前綴事件閉包中;
60、若前綴事件閉包中存在兩個不同的鎖申請事件ea1和鎖申請事件ea2,且該鎖申請事件ea1和該鎖申請事件ea2嘗試申請同一個互斥鎖,則將該鎖申請事件ea1和該鎖申請事件ea2對應的鎖釋放事件er1和鎖釋放事件er2加入到前綴事件閉包中;
61、進一步地,基于所述前綴事件閉包的事件集合和偏序集合構建一有向圖后,在所述有向圖基礎上求解偏序閉包,以得到所述待測目標程序的并發缺陷檢測結果,包括:
62、提取所述前綴事件閉包中的偏序集合,所述偏序集合包括:程序偏序、觀察偏序、鎖義偏序和待測序列中的偏序;
63、將所述前綴事件閉包中所有出現的事件作為有向圖的節點,并結合所述偏序集合構建一有向圖;
64、針對觀察偏序和鎖義偏序執行閉包計算后,進而根據偏序關系的傳遞性執行閉包計算;其中,求解偏序閉包過程中,會針對觀察偏序、鎖義偏序執行閉包計算,并進一步根據偏序關系的傳遞性執行閉包計算;其中,所述閉包計算是指持續進行偏序關系的傳遞,直至不能通過傳遞性推理出新的偏序關系為止;
65、如果偏序閉包求解結果顯示有向圖中無環路產生,則待驗證序列能夠真實發生,所述待測目標程序存在并發缺陷;
66、如果偏序閉包求解結果顯示有向圖中有環路產生,則待驗證序列不能夠真實發生,所述待測目標程序不存在并發缺陷。
67、一種多線程程序和協議中并發缺陷的檢測系統,包括:
68、插樁與序列收集模塊,用于生成待測目標程序的原始事件序列,所述待測目標程序為采用多線程執行命令的用戶程序或運行多線程協議的系統程序,所述原始事件序列中的原始事件包括:內存讀/寫事件、鎖申請/釋放事件、內存申請/釋放事件和分支事件;
69、序列精簡模塊,用于移除所述原始事件序列中只涉及單線程獨占變量和只讀變量的事件,得到精簡事件序列;
70、數據依賴分析模塊,用于基于所述精簡事件序列,構建數據依賴圖,并根據所述數據依賴圖中的通路信息,分析并還原出所述待測目標程序運行時的數據流動狀況,進而識別可能存在并發內存訪問行為的事件對;
71、待驗證序列構造模塊,用于根據待測缺陷類型,查找對應的可能存在并發內存訪問行為的事件對,以構建具有潛在缺陷的待驗證序列;
72、序列分析模塊,用于計算所述待驗證序列中所有事件的前綴事件閉包,并基于所述前綴事件閉包的事件集合和偏序集合構建一有向圖后,在所述有向圖基礎上求解偏序閉包,以得到并發缺陷檢測結果。
73、本發明與現有技術相比,具有以下優勢:
74、1.利用偏序關系,將多種并發缺陷的檢測轉化為待驗證序列的驗證,提供了針對多種并發缺陷的通用檢測技術。
75、2.通過分析事件間的數據依賴,并對可疑事件集合中的事件進行重新排序,構建出可以觸發并發漏洞的待檢測序列,本發明能夠在保證沒有誤報的前提下,放松現有技術“保持控制流和數據流完全不變”的限制,允許待檢測序列與原始事件序列擁有不同的指針數據流,提升了在單次檢測過程中對線程交錯狀態空間的覆蓋度,從而在單次檢測過程中能夠檢測到更多的并發缺陷。本發明的可靠性(即不會產生誤報)可通過嚴格的理論推理證明。
76、3.利用事件間的觀察數據依賴、值數據依賴以及地址數據依賴關系,本發明離線構建數據依賴圖以還原程序運行時數據在指令之間的流動狀況,從而通過離線分析的手段分析得出程序在運行時可能存在的并發內存訪問行為,以及可能導致程序出現線程不安全性的漏洞點,進而開展缺陷檢測。本發明只需記錄程序運行時的執行軌跡,不需要在程序運行時對程序狀態進行監控或進行安全檢查,因此不會像以往的在線漏洞檢測技術一樣帶來給程序帶來巨大的運行時開銷。同時,本發明對缺陷檢測手段沒有要求,即可以同時采用多種技術手段、進行多種類型缺陷的檢查,因此可擴展性高、對新技術的適配性較好。