馬銀雪,李文明,陳 哲
(南京航空航天大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,江蘇 南京 210016)
C 語言因具有執(zhí)行效率高、可移植性強(qiáng)的特點(diǎn),被廣泛應(yīng)用在各種編程壞境中,特別是在嵌入式系統(tǒng)、機(jī)載軟件等底層的、對程序執(zhí)行效率要求較高的軟件編寫中。但C 程序的高執(zhí)行效率是以不進(jìn)行完全的內(nèi)存管理換來的,它們不會在訪問內(nèi)存時檢測邊界安全,這導(dǎo)致C 程序可能存在嚴(yán)重的安全漏洞。例如最近被發(fā)現(xiàn)的OpenSSL 的Heartbleed 漏洞,它在調(diào)用memcpy 函數(shù)前不進(jìn)行邊界安全檢測,這使攻擊者每次能讀取64 kB 的敏感數(shù)據(jù),導(dǎo)致用戶信息的泄露,并影響了全球2/3 的網(wǎng)站。在2011 年CWE/SANS 最危險的25 個軟件漏洞排行榜上,“未檢測輸入大小的緩存區(qū)復(fù)制漏洞”,也就是緩存區(qū)溢出漏洞排名第3。最新的CNVD 統(tǒng)計(jì)結(jié)果也顯示,在所有漏洞中,邊界條件錯誤漏洞出現(xiàn)次數(shù)排名第3。由此可見,未檢測邊界安全導(dǎo)致的軟件安全形勢依然嚴(yán)峻。
目前已存在多種邊界安全檢測技術(shù)。基于對象技術(shù)[1-9]記錄程序運(yùn)行過程中產(chǎn)生的對象地址范圍,通過對象訪問時判斷訪問地址是否在有效區(qū)間來進(jìn)行邊界安全檢測;擴(kuò)展指針技術(shù)[10-13]擴(kuò)展了指針的數(shù)據(jù)類型,新的數(shù)據(jù)類型能額外包含指針?biāo)赶蚩臻g的地址范圍,在指針訪問時根據(jù)其地址范圍來進(jìn)行指針有效性檢測;值驗(yàn)證技術(shù)[14-15]在與緩存區(qū)相鄰的內(nèi)存區(qū)域插入一個隨機(jī)值,通過判斷隨機(jī)值是否被修改來確定訪問是否越界;影子內(nèi)存技術(shù)[16-17]是把每一塊內(nèi)存狀態(tài)映射到某一個固定的內(nèi)存區(qū)域,通過內(nèi)存映射狀態(tài)的改變來進(jìn)行越界判斷。它們都能進(jìn)行有效的內(nèi)存安全檢測,但是也存在相應(yīng)的缺陷?;谥羔樇夹g(shù)修改了原指針的數(shù)據(jù)類型,會導(dǎo)致程序產(chǎn)生兼容性問題;值驗(yàn)證技術(shù)主要檢測棧緩存區(qū)溢出,難以用于檢測其它位置的內(nèi)存安全;影子內(nèi)存技術(shù)要對每一塊內(nèi)存進(jìn)行映射,當(dāng)平臺的內(nèi)存機(jī)制不同時(如大小端問題),映射方法也不同,故可移植性差?;趯ο蠹夹g(shù)不會改變原有程序的語法結(jié)構(gòu),因而不存在兼容性問題;它不依賴于具體的運(yùn)行平臺,故也不存在移植性差的問題;該技術(shù)能對每一塊內(nèi)存的地址范圍進(jìn)行記錄,故檢測范圍廣泛,但是它還存在一些問題。
本文首先分析基于對象技術(shù)的邊界安全檢測技術(shù)和近年來的技術(shù)發(fā)展,介紹該技術(shù)存在的2 個缺陷,一是對錯誤的檢測不完全,二是插樁后程序的執(zhí)行效率低下。
針對缺陷1,改進(jìn)多維數(shù)組維間越界和結(jié)構(gòu)體內(nèi)成員變量越界訪問的檢測,改進(jìn)檢測指針訪問時的指針指向從一個有效內(nèi)存塊偏移到另一個有效內(nèi)存塊時的情況。針對缺陷2,基于文獻(xiàn)[9]的Frama-C,提出用平衡二叉樹實(shí)現(xiàn)存儲結(jié)構(gòu),進(jìn)一步降低插樁對程序執(zhí)行效率的影響。
最后,介紹一個原型系統(tǒng)Boundcheck,并用實(shí)驗(yàn)證明改進(jìn)技術(shù)的有效性。
基于對象的技術(shù)最早由文獻(xiàn)[1]提出,在此之后獲得大量改進(jìn)。它對C 程序的指針和數(shù)組進(jìn)行邊界檢測。在對象創(chuàng)建時得到對象的基地址和大小信息(即記錄),存放在存儲結(jié)構(gòu)中,在銷毀時刪除。對象包括靜態(tài)定義和動態(tài)分配的對象。靜態(tài)對象包括靜態(tài)全局變量和局部變量(棧變量),動態(tài)對象指堆上動態(tài)分配的變量。在所有包括算術(shù)運(yùn)算和取值操作的指針操作中,先根據(jù)指針指向空間的地址查詢存儲結(jié)構(gòu),檢查是否包含這個地址記錄,若存在相應(yīng)的記錄,則返回,若不存在,說明地址無效。流程如圖1 所示。
圖1 基于對象技術(shù)的流程圖
文獻(xiàn)[2-3]用malloc 函數(shù)創(chuàng)建一個Out Of Bounds (OOB)對象,該對象用來記錄指針越界時的位置,并通過添加的OOB 對象操作解決指針后續(xù)操作檢測問題,即當(dāng)某一指針訪問出錯后,基于此指針的后續(xù)操作能被檢測。文獻(xiàn)[4-5]使用哈希表存儲指針的基地址和邊界信息,通過改變源代碼的調(diào)用形式和函數(shù)聲明,傳遞函數(shù)調(diào)用時的參數(shù)邊界信息,最終提高了插樁后的程序執(zhí)行效率。文獻(xiàn)[6]用分配的內(nèi)存塊的地址范圍替代對象原占有的空間的地址范圍。文獻(xiàn)[7]把指針分為2 類,分別為solid 類和nonsolid 類,為每一個solid 類指針分配一個能隨著指針運(yùn)算更新的邊界變量,并用基于對象的技術(shù)進(jìn)行訪問檢測。文獻(xiàn)[8]用三元組<base,bound,id >p表示指針p 指向的下界、上界和指針編號,用二元組<base,bound >id表示對象的下界、上界和編號。文獻(xiàn)[9]的Frama-C 提出以Patricia trie 結(jié)構(gòu)存儲地址信息,這大幅降低了樁函數(shù)對程序執(zhí)行性能的影響。
分析以往的這些檢測技術(shù)可知,基于對象的運(yùn)行時驗(yàn)證技術(shù)有3 個關(guān)鍵,分別是地址信息記錄、取值檢測與存儲結(jié)構(gòu)。要想對程序進(jìn)行完全的檢測,就要有兼容性強(qiáng)的地址范圍記錄和取值檢測方法;要使插樁后程序的執(zhí)行效率仍然保持較高,就要尋找合適的數(shù)據(jù)結(jié)構(gòu)作為存儲結(jié)構(gòu)。
綜合分析基于對象技術(shù)的發(fā)展,發(fā)現(xiàn)基于對象的檢測技術(shù)存在2 個缺陷,分別是:
1)對錯誤的檢測不完全,包括下面3 點(diǎn):
①沒有檢測多維數(shù)組的維間越界。
當(dāng)數(shù)組最低維越界時,將產(chǎn)生2 種情況,一種是返回該數(shù)組上的數(shù)據(jù),另一種是返回與該數(shù)組相鄰的內(nèi)存中的數(shù)據(jù)。傳統(tǒng)的基于對象技術(shù)把多維數(shù)組所占的空間看成一個大的整體,在處理時就會丟失每一維的邊界長度,因此無法區(qū)分上述2 種情況。例如對以下多維數(shù)組:
有取值操作1:example1[0][0][i]和取值操作2:example1[2][3][i]。當(dāng)i >4 時,例如i 為5,操作1的訪問等價于example1[0][1][ 0]。操作2 訪問的是數(shù)組example1 的最后一個元素的下一個位置上的值。
②把對象作為一個整體節(jié)點(diǎn),只能檢測這個整體所在的地址范圍邊界。
當(dāng)對象是一個復(fù)雜的數(shù)據(jù)類型,例如是一個包含數(shù)組成員的結(jié)構(gòu)體,由于將這個結(jié)構(gòu)體看成一個整體,因此不能檢測結(jié)構(gòu)體中數(shù)組成員的邊界。例如對以下結(jié)構(gòu)體:
當(dāng)進(jìn)行* (example2.str +i)操作時,其中i 是一個具體的偏移值,就不能判斷對成員變量str 的訪問是否超出了它所指向空間的邊界。
③不能檢測指針從一個有效位置偏移到另一個有效位置的情況。
基于對象的技術(shù)只知道要查找的地址是否存放在存儲結(jié)構(gòu)某一條記錄中,而不知道找到的這條記錄是否為真正要找的記錄。
例如對以下定義的3 個變量:
取值運(yùn)算* (p+1)在地址向上生長的系統(tǒng)里的值為1。傳統(tǒng)的基于對象技術(shù)根據(jù)p +1 的地址查詢存儲結(jié)構(gòu),并找到對象a 的記錄,將判斷* (p +1)的訪問在對象a 的地址范圍內(nèi),因此不產(chǎn)生漏洞報告。但實(shí)際上p 原來指向?qū)ο骲,p+1 已經(jīng)偏移出了對象b 的地址范圍。這樣的操作可能產(chǎn)生嚴(yán)重的安全隱患,因此應(yīng)該能被檢測出來。
2)由于存在大量對存儲結(jié)構(gòu)中記錄的添加、查找、刪除操作,插樁對程序的執(zhí)行性將產(chǎn)生巨大的影響。
根據(jù)圖1 所示流程,利用編譯器的詞法分析、語法分析生成包含源代碼信息的抽象語法樹,并根據(jù)抽象語法樹上的節(jié)點(diǎn)類型進(jìn)行插樁。在變量定義處插入樁函數(shù)記錄塊地址范圍;在數(shù)組訪問、指針訪問、指針的算術(shù)運(yùn)算處插入函數(shù)檢測訪問是否越界;在庫函數(shù)調(diào)用處替換庫函數(shù)名;改進(jìn)存儲結(jié)構(gòu)使其用平衡二叉樹實(shí)現(xiàn)。
對程序中出現(xiàn)的對象,都會插入相應(yīng)代碼,這些代碼程序運(yùn)行時記錄對象所占空間的基地址(base)和上界地址(bound),這就為指針的越界檢測提供了數(shù)據(jù)基礎(chǔ)。
2.1.1 棧對象
以往的基于對象技術(shù)不細(xì)分對象,而是把一個對象看成一個整體內(nèi)存塊。本文根據(jù)對象是由單個數(shù)據(jù)類型還是由多個數(shù)據(jù)類型組成,把棧對象細(xì)分為簡單對象與復(fù)雜對象。復(fù)雜對象因組合方式不同,又分為固定長度數(shù)組與結(jié)構(gòu)體變量。簡單對象處理方式不變,復(fù)雜對象因組合方式不同,處理的方式也不同。
1)固定長度數(shù)組。
多維數(shù)組(其中一維數(shù)組可看成高維長度為0 的多維數(shù)組)如果作為函數(shù)參數(shù)傳遞到其它函數(shù)內(nèi),會丟失維度信息,這導(dǎo)致被調(diào)用函數(shù)無法判斷該數(shù)組的某一維是否越界。把最低一維看作一個內(nèi)存塊,因此多維數(shù)組就可看作有限個連續(xù)的內(nèi)存塊,這樣就可以記錄每一個內(nèi)存塊的地址范圍,例如對以下多維數(shù)組:
內(nèi)存塊記錄的形式為:
它一共記錄了3×4 個大小為sizeof(int)* 5 的內(nèi)存塊。
2)結(jié)構(gòu)體變量。
結(jié)構(gòu)體中可能存在復(fù)雜的成員變量,但由結(jié)構(gòu)體成員訪問越界引起的漏洞,則主要是由固定長度數(shù)組或未知長度字符串?dāng)?shù)組的成員變量引起,因此本文只考慮這2 個成員類型。
①固定長度數(shù)組成員。
由于C 語言的語法限制,不能按步驟1)中方法轉(zhuǎn)換,于是從數(shù)組的類型信息中提取數(shù)組的長度值,例如對結(jié)構(gòu)體中的3 種數(shù)組:
int a[4];數(shù)組類型為int[4],可提取出長度為4。struct test1 example3[10];數(shù)組的類型為struct test1[10],可提取出長度為10。
int array[3][4][5];數(shù)組的類型為int[3][4][5],可提取出每一維的長度分別為3、4、5。
②字符指針成員。
對未知長度字符串?dāng)?shù)組,在結(jié)構(gòu)體初始化時另取一個新指針指向字符串,通過新指針就能訪問到賦值的字符串。例如對以下結(jié)構(gòu)體:
字符串命名后用_str_0 作為新指針,并賦值給stu->str,根據(jù)該指針指向空間的地址范圍,就能對成員變量str 進(jìn)行越界檢測:
2.1.2 堆對象
當(dāng)在堆上用malloc 函數(shù)創(chuàng)建對象時,用新函數(shù)名替換源代碼中的malloc 函數(shù)名,使程序運(yùn)行時每次調(diào)用malloc 函數(shù)都轉(zhuǎn)換成調(diào)用新函數(shù)。這個新函數(shù)不僅具有原malloc 函數(shù)內(nèi)存分配功能,還能記錄所分配內(nèi)存塊的起始地址和結(jié)束地址,但如果malloc 函數(shù)分配失敗,則不記錄。如下例:
以往的基于對象技術(shù)檢測時只進(jìn)行一次地址查詢操作,只知道要查找的地址是否存放在存儲結(jié)構(gòu)某一條記錄中,而不知道找到的這條記錄是否為真正要找的記錄。針對該問題,本文用2 次地址查詢操作檢測取值運(yùn)算。第1 次的查詢用指針未偏移前的地址,得到被操作對象的記錄,第2 次查詢用指針偏移后的地址,得到當(dāng)前操作對象的記錄。若2 個記錄相同,說明指針偏移未越界,否則表示指針偏移到另一個對象上。地址取值運(yùn)算分為數(shù)組訪問和指針訪問2 類。
1)數(shù)組訪問。
當(dāng)訪問已知長度的數(shù)組時,用一個函數(shù)調(diào)用改寫該數(shù)組的索引。這個函數(shù)處理當(dāng)前數(shù)組的類型信息,繼而得到數(shù)組定義長度,最后比較索引值是否在定義的長度范圍內(nèi)。若在范圍內(nèi),函數(shù)返回原索引值,否則提示數(shù)組訪問越界。例如定義數(shù)組array[6],訪問操作為array[i],改寫索引后:
其中c1、c2、func_name 分別表示array[i]在原程序中位置的行列號、所屬函數(shù)的函數(shù)名,_RV_insert_check函數(shù)判斷i 是否在0~6 范圍內(nèi),如是則返回i 值,否則輸出提示數(shù)組越界信息。
2)指針訪問。
通過改寫整個指針訪問表示式,用當(dāng)前地址取值之前要訪問的基地址和當(dāng)前地址查詢存儲結(jié)構(gòu),比較是否存在相應(yīng)的內(nèi)存塊,若不存在或是2 次查詢得到的內(nèi)存塊不同,說明指針訪問出錯。例如對以下程序片段:
把p[i]改寫為:
把* (p+i)改寫為:
其中,__boundcheck_ptr_reference 函數(shù)判斷p[0](p)和p[i](p+i)的地址在存儲結(jié)構(gòu)中是否存在對應(yīng)的內(nèi)存塊且相同。
指針越界不僅能發(fā)生在取值表達(dá)式上,還能發(fā)生在指針的算術(shù)運(yùn)算上。文獻(xiàn)[18]認(rèn)為指針的算術(shù)運(yùn)算是導(dǎo)致指針越界訪問發(fā)生的根本原因。首先提取算術(shù)表達(dá)式的基地址,再判斷基地址所在的對象記錄是否為運(yùn)算后的地址所在的對象記錄,若相同,則沒有越界,否則,提示指針?biāo)阈g(shù)運(yùn)算越界。例如有指針p 和q:
在第4 條語句前插入函數(shù):
該函數(shù)根據(jù)p 和p+6 的地址查詢相應(yīng)的對象記錄,如果記錄不同,那么p+6 越界。
標(biāo)準(zhǔn)C 庫函數(shù)不提供邊界檢測的功能,本文在源代碼中替換庫函數(shù)名。替換后的函數(shù)先檢測邊界安全,只有滿足邊界條件時才調(diào)用原有的庫函數(shù)。
例如對字符串處理函數(shù)strcpy(dest,src),用_boundcheck_strcpy(dest,src)替換之。這個新函數(shù)先檢查dest 所對應(yīng)內(nèi)存空間的長度是否大于strlen(src),若是則調(diào)用strcpy 函數(shù),否則輸出提示庫函數(shù)復(fù)制越界的信息。
針對1.2 節(jié)中提出的基于對象技術(shù)的缺陷2),參照文獻(xiàn)[9]中Frama-C 存儲結(jié)構(gòu)的實(shí)現(xiàn)方式,本文首先實(shí)現(xiàn)了二叉排序樹(BST)、伸展樹(Splay Tree)、列表(Lists)和Patricia trie 作為存儲結(jié)構(gòu),并實(shí)現(xiàn)用平衡二叉樹(AVL)來優(yōu)化存儲結(jié)構(gòu)。
由于內(nèi)存分配的地址順序通常是線性的,因此用BST 和Lists 作為存儲結(jié)構(gòu)時,該存儲結(jié)構(gòu)也是線性的,因此查找時間隨著記錄增加線性增大。Splay Tree 本質(zhì)上也是二叉排序樹,只是在每次查找后會重構(gòu)原樹,把查找過的記錄放入樹根處,除了那些具有大量重復(fù)查詢的程序,這對改善線性存儲結(jié)構(gòu)的查詢性作用不大。Patricia trie 是Frama-C 改進(jìn)的一棵以前綴樹為基礎(chǔ)的結(jié)構(gòu)。該樹將對象的地址范圍記錄存放在葉子節(jié)點(diǎn)上,查找則是從樹根開始向下遍歷,直到葉子節(jié)點(diǎn)。它的最好查找長度是樹的深度,最壞的查找次數(shù)則是該樹的節(jié)點(diǎn)數(shù)。
用平衡二叉樹(AVL)優(yōu)化存儲結(jié)構(gòu)。AVL 相比線性結(jié)構(gòu)減小了查找深度,相比Patricia trie 結(jié)構(gòu),查找不一定要遍歷樹節(jié)點(diǎn)。AVL 最好的查找長度是1,即查找的記錄存放在根節(jié)點(diǎn)上,最壞的查找長度則是樹的深度。
圖2 Boundcheck 作用圖
基于開源編譯器Clang 和第2 節(jié)中的改進(jìn)技術(shù)開發(fā)一個檢測邊界訪問越界的運(yùn)行時驗(yàn)證工具Boundcheck。Boundcheck 的主要結(jié)構(gòu)包括源代碼插樁器、存儲結(jié)構(gòu)實(shí)現(xiàn)文件以及樁函數(shù)實(shí)現(xiàn)文件。源代碼插樁器包含了塊地址范圍記錄、指針取值運(yùn)算、指針?biāo)阈g(shù)運(yùn)算、庫函數(shù)檢測等功能塊。存儲結(jié)構(gòu)文件包括BST、Splay Tree、Lists、Patricia trie 和AVL 實(shí)現(xiàn)文件。樁函數(shù)實(shí)現(xiàn)文件則對插入源代碼中的函數(shù)進(jìn)行實(shí)現(xiàn)。工具的作用圖如圖2 所示。
在Ubuntu12.04、Intel(R)Core(TM)i3-2330M CPU 平臺上測試Boundcheck 的運(yùn)行效果。用Mibench[19]進(jìn)行性能測試,并對OpenSSL 中的Heartbleed 漏洞進(jìn)行擴(kuò)展測試。
3.2.1 性能測試
使用Mibench 基準(zhǔn)程序中自帶的輸入數(shù)據(jù)和測試命令,并修改Makefile 文件,使它能鏈接到Boundcheck 庫文件。
測試結(jié)果如表1 所示。第1 列程序名的small 和large 分別代表小數(shù)據(jù)集和大數(shù)據(jù)集,第2 列Original表示未進(jìn)行插樁的原程序運(yùn)行時間,其余列表示使用相應(yīng)數(shù)據(jù)結(jié)構(gòu)作為存儲結(jié)構(gòu)進(jìn)行插樁后的程序運(yùn)行時間。
表1 不同數(shù)據(jù)結(jié)構(gòu)作存儲結(jié)構(gòu)的程序執(zhí)行時間/s
分析表1 可知,使用Patricia trie 結(jié)構(gòu)和AVL 樹,程序的運(yùn)行時間比前3 種線性結(jié)構(gòu)都要少很多,而使用AVL 樹相比Patricia trie 的查詢效率要更高,更接近原程序運(yùn)行時間。
3.2.2 擴(kuò)展測試
Heartbleed 漏洞產(chǎn)生的原因是在調(diào)用memcpy 函數(shù)前不進(jìn)行邊界檢測。對memcpy(bp,pl,payload)函數(shù),如果內(nèi)存空間塊從p1 指向的位置開始,后面沒有payload 大小的有效數(shù)據(jù)時,memcpy 函數(shù)仍然拷貝相鄰空間的payload 長度的數(shù)據(jù)到bp 指向的緩存區(qū)內(nèi),最終導(dǎo)致敏感數(shù)據(jù)的泄露。
用Boundcheck 檢測時,先用新函數(shù)名替換memcpy,再查詢p1 指向的內(nèi)存塊的地址范圍(base,bound),并判斷(size_t)(bound-p1)>payload 是否成立。如果成立,則memcpy 能合法拷貝payload 長度的數(shù)據(jù),那么將執(zhí)行原memcpy 函數(shù);如果不成立提示庫函數(shù)復(fù)制越界。
通過分析插樁后的代碼發(fā)現(xiàn),Boundcheck 能夠在相應(yīng)的位置進(jìn)行正確的插樁,能檢測Heartbleed 漏洞。
C 語言不檢測內(nèi)存邊界導(dǎo)致編寫好的C 程序潛伏著安全漏洞,限制了它應(yīng)用在安全性要求高的軟件編寫中。本文針對C 語言內(nèi)存邊界安全檢測問題,首先介紹了原有的基于對象的運(yùn)行時驗(yàn)證技術(shù),并總結(jié)了2 個原有技術(shù)的缺陷,一是檢測范圍較窄,二是插樁對程序執(zhí)行效率影響較大。本文改進(jìn)這2 個缺陷,設(shè)計(jì)了一個原型系統(tǒng)Boundcheck 并進(jìn)行實(shí)驗(yàn)。性能測試結(jié)果表明,平衡二叉樹作為存儲結(jié)構(gòu)能降低插樁對程序執(zhí)行效率的影響;擴(kuò)展測試表明,對地址范圍記錄、取值檢測等的改進(jìn)能擴(kuò)大檢測范圍。
[1]Jones R W M,Kelly P H J.Backwards-compatible bounds checking for arrays and pointers in C programs[C]// Proceedings of the 3rd International Workshop on Automated and Algorithmic Debugging.1997:13-26.
[2]Ruwase O,Lam M S.A practical dynamic buffer overflow detector[C]// Proceedings of the 11th Symposium on Network and Distributed System Security.2004:159-169.
[3]Dhurjati D,Adve V.Backwards-compatible array bounds checking for C with very low overhead[C]// Proceedings of the 28th International Conference on Software Engineering.2006:162-171.
[4]Nagarakatte S,Zhao Jianzhou,Martin M M K,et al.Soft-Bound:Highly compatible and complete spatial memory safety for C[C]// Proceedings of the 30th ACM SIGPLAN Conference on Programming Language Design and Implementation.2009:245-258.
[5]Nagarakatte S,Zhao Jianzhou,Martin M M K,et al.CETS:Compiler-enforced temporal safety for C[C]// Proceedings of the 2010 ACM International Symposium on Memory Management.2010:31-40.
[6]Akritidis P,Costa M,Castro M,et al.Baggy bounds checking:An efficient and backwards-compatible defense against out-of-bounds errors[C]// Proceedings of the 18th USENIX Security Symposium.2009:51-66.
[7]Yuan Jun,Johnson R.CAWDOR:Compiler assisted worm defense[C]// Proceedings of the 12th IEEE International Working Conference on Source Code Analysis and Manipulation (SCAM).2012:54-63.
[8]Simpson M S,Barua R K.MemSafe:Ensuring the spatial and temporal memory safety of C at runtime[J].Software:Practice and Experience,2013,43(1):93-128.
[9]Kosmatov N,Petiot G,Signoles J.An optimized memory monitoring for runtime assertion checking of C programs[C]// Proceedings of the 4th International Conference on Runtime Verification.2013:167-182.
[10]Jim T,Morrisett J G,Grossman D,et al.Cyclone:A safe dialect of C[C]// Proceedings of the General Track:2002 USENIX Annual Technical Conference.2002:275-288.
[11]Necula G C,Condit J,Harren M,et al.CCured:Typesafe retrofitting of legacy software[J].ACM Transactions on Programming Languages and Systems,2005,27(3):477-526.
[12]Xu Wei,DuVarney D C,Sekar R.An efficient and backwards-compatible transformation to ensure memory safety of C programs[C]// Proceedings of the 12th ACM SIGSOFT International Symposium on Foundations of Software Engineering.2004:117-126.
[13]Oiwa Y.Implementation of the memory-safe full ANSI-C compiler[C]// Proceedings of the 2009 ACM SIGPLAN Conference on Programming Language Design and Implementation.2009:259-269.
[14]Cowan C,Pu C,Maier D,et al.StackGuard:Automatic adaptive detection and prevention of buffer-overflow attacks[C]// Proceedings of the 7th USENIX Security Symposium.1998:63-78.
[15]Hasabnis N,Misra A,Sekar R.Light-weight bounds checking[C]// Proceedings of the 10th International Symposium on Code Generation and Optimization.2012:135-144.
[16]Seward J,Nethercote N.Using Valgrind to detect undefined value errors with bit-precision[C]// Proceedings of the General Track:2005 USENIX Annual Technical Conference.2005:17-30.
[17]Bruening D,Zhao Qin.Practical memory checking with Dr.Memory[C]// Proceedings of the 9th Annual IEEE/ACM International Symposium on Code Generation and Optimization.2011:213-223.
[18]Younan Y,Philippaerts P,Cavallaro L,et al.PAriCheck:An efficient pointer arithmetic checker for C programs[C]// Proceedings of the 5th ACM Symposium on Information,Computer and Communications Security.2010:145-156.
[19]Guthaus M R,Ringenberg J S,Ernst D,et al.MiBench:A free,commercially representative embedded benchmark suite[C]// Proceedings of the 2001 IEEE International Workshop on Workload Characterization.2001:3-14.