張琦 劉一辰
摘? 要:C語言廣泛應(yīng)用于嵌入式軟件和系統(tǒng)軟件的開發(fā),它提供了更直接的底層內(nèi)存控制,但卻缺少對內(nèi)存訪問安全性的檢測,導(dǎo)致C程序運行時可能產(chǎn)生內(nèi)存安全性錯誤。當(dāng)前,開發(fā)人員力求通過多種驗證技術(shù)解決內(nèi)存安全性錯誤,最常用的是運行時驗證技術(shù)。文章首先對C程序常見的內(nèi)存安全性錯誤進(jìn)行分析,然后介紹幾種相關(guān)的內(nèi)存分析技術(shù),最后分別對幾種常用的C程序內(nèi)存安全性檢測工具進(jìn)行介紹和比較,為接下來的研究工作提供了方向性參考。
關(guān)鍵詞:C程序;內(nèi)存錯誤;運行時驗證;AddressSanitizer;Movec
中圖分類號:TP311? ? ?文獻(xiàn)標(biāo)識碼:A文章編號:2096-4706(2021)23-0084-04
Overview of C Language Memory Safety Runtime Verification Technology
ZHANG Qi, LIU Yichen
(College of Computer Science and Technology, Nanjing University of Aeronautics and Astronautics, Nanjing? 211106, China)
Abstract: C language is widely used in the development of embedded software and system software. It provides more direct underlying memory control but lacks the detection of memory access security, which causes memory security errors when C programs are running. At present, developers strive to solve memory security errors through a variety of verification technologies, the most commonly used is runtime verification technology. This paper first analyzes common memory security errors in C programs, then introduces several related memory analysis techniques, and finally introduces and compares several commonly used C program memory security detection tools. It provides direction reference for the following research work.
Keywords: C program; memory error; runtime verification; Address Sanitizer; Movec
0? 引? 言
隨著社會的不斷發(fā)展,信息化為人們的生產(chǎn)生活帶來極大的便利。生活中的方方面面都離不開計算機(jī)軟件的應(yīng)用,如在線教育、智能交通服務(wù)、遠(yuǎn)程醫(yī)療、5G通信以及各種社交、辦公等領(lǐng)域。計算機(jī)軟件在給人們帶來便利的同時,也潛藏著一些安全問題。OpenSSL本身是一個用于安全通信,可以保證數(shù)據(jù)機(jī)密性和可靠性的應(yīng)用程序。然而,在2014年,OpenSSL被爆出“心臟滴血”重大漏洞,攻擊者通過這一漏洞,可以獲取應(yīng)用程序源碼、用戶的網(wǎng)絡(luò)訪問請求和用戶的cookie信息,甚至可以獲取到用戶的電子郵件、銀行卡賬號密碼等信息,給用戶帶來不可估量的損失。RPC遠(yuǎn)程過程調(diào)用是一個進(jìn)程通信機(jī)制,允許一臺計算機(jī)遠(yuǎn)程執(zhí)行另一臺計算機(jī)上的代碼。2003年,利用RPC一個漏洞的蠕蟲“沖擊波”在互聯(lián)網(wǎng)上傳播,感染了上百萬臺計算機(jī)。該病毒會建立一個“后門”,允許攻擊者遠(yuǎn)程控制被感染的計算機(jī),使其系統(tǒng)崩潰。根據(jù)保守估算,“沖擊波”造成至少5億美元的經(jīng)濟(jì)損失,而起因卻是源于代碼中存在一個緩沖區(qū)溢出漏洞。為了保證軟件使用的可靠性和信息的安全性,越來越多的技術(shù)注重于檢測軟件系統(tǒng)的內(nèi)存安全性。當(dāng)前,主流的軟件驗證技術(shù)包括軟件測試、程序靜態(tài)分析、模型檢測和運行時驗證等。
C語言編寫的程序具有運行速度快、執(zhí)行效率高等特點,因此C語言廣泛應(yīng)用于嵌入式系統(tǒng)軟件的開發(fā)。同時它提供了更直接的底層內(nèi)存控制,但卻缺少對內(nèi)存訪問安全性的檢測,導(dǎo)致C程序運行時可能產(chǎn)生內(nèi)存安全性錯誤,比如內(nèi)存泄漏、緩沖區(qū)溢出、多次釋放等。因此,對C語言的內(nèi)存安全性進(jìn)行驗證是十分重要的。
1? C程序內(nèi)存錯誤
借鑒Safe-C的分類方法,可以將C程序的內(nèi)存錯誤分為空間內(nèi)存錯誤和時間內(nèi)存錯誤??臻g內(nèi)存錯誤是指對內(nèi)存上下界范圍外的空間進(jìn)行非法的訪問或修改,比如,對空指針進(jìn)行解引用、緩沖區(qū)溢出,訪問非法指針等。時間內(nèi)存錯誤是指訪問已經(jīng)釋放的內(nèi)存,比如,釋放后使用(UAF)、解引用懸掛指針、多次釋放、非法釋放等。
如圖1所示為幾種常見的空間內(nèi)存錯誤。
圖1列出了幾種C程序常見空間內(nèi)存錯誤,如圖2所示為幾種常見的時間內(nèi)存錯誤。
2? 運行時驗證技術(shù)
動態(tài)分析技術(shù)在運行程序的基礎(chǔ)上,通過監(jiān)測程序的執(zhí)行情況來收集程序的運行時行為,并對其進(jìn)行分析,檢查程序是否存在內(nèi)存安全性問題。下面介紹幾種常見的運行時驗證技術(shù):
(1)值驗證技術(shù)。由Crispan Cowan等人提出,主要用于檢測緩沖區(qū)溢出問題。值驗證技術(shù)的原理是在局部變量緩存區(qū)和函數(shù)返回地址之間插入一個安全變量。局部變量緩沖區(qū)一旦溢出,如果攻擊者試圖修改函數(shù)的返回地址,則該安全變量也會隨之被更改??梢酝ㄟ^檢測安全變量是否被修改來檢測程序是否被惡意攻擊。由于值驗證技術(shù)是通過在棧上插入安全變量的方式來檢測緩沖區(qū)溢出問題,因此該方法無法檢測堆內(nèi)存和全局的緩沖區(qū)溢出問題,同時也無法檢測時間內(nèi)存錯誤,有很大的局限性。
(2)基于對象技術(shù)。由Jones和Kelly提出,主要用于檢測內(nèi)存越界等問題。它的主要思想是存儲程序中所有對象的上下邊界,而非存儲各個指針,這樣做的好處是多個指針指向同一個對象時只需記錄一次,從而節(jié)省存儲空間。對指針進(jìn)行解引用訪問時,在指針元數(shù)據(jù)表中查詢指針的地址值,檢查指針值是否在上下界之間,如果指針值在上下界之間,則訪問合法。采用這種方式保證了對象內(nèi)存布局的完整性,同時也會記錄堆內(nèi)存的空間分配邊界信息。但是該技術(shù)最大的缺點是無法解決子對象問題。
(3)寬指針(fat-pointer)技術(shù)。顧名思義,指針不再只存有內(nèi)存地址信息,還存有該指針?biāo)赶騼?nèi)存塊的基地址和大小等信息。Safe-C就是在寬指針的基礎(chǔ)之上,額外增加了指針變量的存儲類型和引用計數(shù),不僅可以檢測內(nèi)存越界等問題,還能處理部分時間內(nèi)存錯誤。由于寬指針技術(shù)更改了原有的指針結(jié)構(gòu),會導(dǎo)致插樁后的代碼與未插樁代碼(比如庫函數(shù))不兼容,并且插樁后的指針結(jié)構(gòu)變得復(fù)雜,致使程序執(zhí)行效率低下。
(4)基于指針的技術(shù)。其思想與寬指針類似,不同的是,該方法將指針的內(nèi)存地址和大小等信息記錄到一個獨立的數(shù)據(jù)結(jié)構(gòu)中,從而不改變原有的指針結(jié)構(gòu)?;谥羔樇夹g(shù)的方法為每一個新創(chuàng)建的指針變量建立一個指針元數(shù)據(jù)pmd,pmd中存儲指針?biāo)笇ο蟮倪吔绲刃畔?。在為指針賦值時,會進(jìn)行指針元數(shù)據(jù)的更新,新指針的指針元數(shù)據(jù)繼承自原指針的指針元數(shù)據(jù)。在對指針進(jìn)行解引用訪問內(nèi)存時,首先需要對該指針的pmd進(jìn)行查詢,判斷訪問地址是否在對象的上下界范圍之內(nèi)以及是否滿足相應(yīng)的類型。
(5)影子內(nèi)存技術(shù)。是指將一個程序內(nèi)存狀態(tài)以某種特定的方式偏移映射到一個特定的空間內(nèi),其中內(nèi)存狀態(tài)中包含了程序中變量存放的地址、內(nèi)存是否被初始化以及其他一些變量的信息等。在對程序中的變量進(jìn)行訪問時,通過查詢其影子空間存儲的該變量的內(nèi)存狀態(tài)來判斷訪問是否合法。
3? 運行時驗證工具
目前,針對C語言比較成熟的動態(tài)分析工具有AddressSantizer、SoftBoundCets、Valgrind、Movec等:
(1)AddressSanitizer是谷歌公司開發(fā)的基于影子內(nèi)存的技術(shù),采用中間代碼插樁實現(xiàn)的動態(tài)檢測工具。該算法的思路是:如果想避免緩沖區(qū)溢出,只需在每塊內(nèi)存區(qū)域的右端(或兩端)加一塊紅色區(qū)域,將內(nèi)存的狀態(tài)信息記錄到影子內(nèi)存中,在對內(nèi)存進(jìn)行操作時可以通過影子內(nèi)存來判斷該內(nèi)存的狀態(tài)。AddressSantizer可以有效檢測緩沖區(qū)溢出、UAF、Double-Free、內(nèi)存泄漏等問題,但卻無法處理子對象越界等問題。
(2)SoftBoundCets由SoftBound和Cets構(gòu)成,同樣采用基于指針的技術(shù)。其中,SoftBound可以檢測空間內(nèi)存錯誤,它記錄每一個指針?biāo)笇ο蟮倪吔缧畔ⅰ6鳦ets可以檢測部分時間內(nèi)存錯誤,它為每個對象維護(hù)一個唯一ID,在訪問該對象內(nèi)存空間時進(jìn)行檢測。但SoftBoundCets卻難以檢測子對象越界、非法訪問庫函數(shù)以及函數(shù)的指針參數(shù)等問題。
(3)Valgrind是一款用于內(nèi)存安全檢測以及性能分析的框架。Memcheck是最廣泛使用的重量級內(nèi)存安全檢測工具,能夠檢測大多數(shù)的內(nèi)存錯誤,比如對未初始化內(nèi)存的訪問、內(nèi)存訪問越界等。它采用二進(jìn)制代碼插樁技術(shù)并結(jié)合影子內(nèi)存技術(shù),記錄程序中內(nèi)存字節(jié)是否具有有效的、已初始化的值,并記錄地址空間是否能夠被讀寫。在操作內(nèi)存空間時,可以通過記錄表來分析檢測程序中的空指針訪問、Double-Free等問題,但無法處理全局變量緩沖區(qū)溢出、子對象越界等問題。
(4)Movec是南京航空航天大學(xué)計算機(jī)科學(xué)與技術(shù)學(xué)院SVLAB實驗室自主開發(fā)的用于C程序運行時監(jiān)控、驗證的自動化工具。Movec采用源代碼插樁技術(shù),利用LLVM和Clang編譯器可以將用Movec語言編寫的有關(guān)安全屬性和監(jiān)控規(guī)范的運行時檢查器插入到C程序中,插樁后的程序可以兼容任何C語言編譯器(例如GCC和其他特定于平臺的編譯器)。Movec采用擴(kuò)展的基于指針的技術(shù),每個指針變量創(chuàng)建并維護(hù)一個指針元數(shù)據(jù)pmd(pointer metadata),圖3(a)定義了pmd的數(shù)據(jù)結(jié)構(gòu)。pmd中存儲了所指向?qū)ο蟮纳舷陆鏱ase和bound信息,同時還存儲了為每個內(nèi)存對象創(chuàng)建并維護(hù)的狀態(tài)節(jié)點snd,圖3(b)定義了snd的數(shù)據(jù)結(jié)構(gòu)。snd中存儲了內(nèi)存對象的狀態(tài)stat和引用計數(shù)count。對象的狀態(tài)包括heap、stack、global、static、function和invalid,而引用計數(shù)記錄指向該對象的指針數(shù)。
4? 實驗對比分析
為了驗證上述工具對C程序內(nèi)存安全性錯誤的檢測能力,本文選用Mibench標(biāo)準(zhǔn)測試集中的部分軟件作為該實驗的實驗數(shù)據(jù)。Mibench中包含了35個用于基準(zhǔn)測試的嵌入式應(yīng)用測試集,它主要是對通用領(lǐng)域的計算能力進(jìn)行評價,Mibench測試集在指令分布、內(nèi)存行為、并行化等方面獨具優(yōu)勢。
本文實驗運行環(huán)境為:處理器選用Intel? Core? i5-7300U CPU、四核、CPU主頻2.60 GHz,內(nèi)存為8 GB,操作系統(tǒng)為64位Ubuntu 16.04.12,編譯器為gcc 5.4.0。實驗結(jié)果如表1所示。
其中,Y表示可以找出程序的內(nèi)存安全性錯誤,N表示無法找出錯誤,/表示程序無法正常運行。從實驗結(jié)果可知,Movec可以找出程序中的大部分錯誤,并準(zhǔn)確地給出了錯誤信息;SoftBoundCets無法檢測出錯誤,并且對部分程序無法正常插樁運行;Valgrind僅發(fā)現(xiàn)了部分錯誤。AddressSantizer的檢測能力與Movec最接近,它發(fā)現(xiàn)了測試集中存在的大多數(shù)錯誤,但是漏報了blowfish中的錯誤。
5? 結(jié)? 論
隨著信息化技術(shù)的快速發(fā)展,人們的生活越來越離不開計算機(jī)軟件的使用,計算機(jī)軟件在給人們生活帶來便利的同時也存在著安全隱患,保證軟件的使用安全變得尤為重要。運行時驗證技術(shù)作為輕量化的驗證方法,能夠有效地檢測系統(tǒng)內(nèi)存安全性方面的漏洞,得到了越來越多的應(yīng)該。本文總結(jié)了幾種常用的運行時驗證技術(shù),對比了幾種流行的運行時驗證工具并進(jìn)行了實驗比較。希望未來能夠推出更多高精尖技術(shù),并且可以將運行時驗證技術(shù)與靜態(tài)分析、模糊測試等技術(shù)相結(jié)合,進(jìn)一步為軟件的內(nèi)存安全性檢測做出貢獻(xiàn)。
參考文獻(xiàn):
[1] John,Matt,Pravir. Network security with openSSL: cryptography for secure communications [M].O’Reilly Media,2002.
[2] 曹志波.OpenSSL的心臟出血漏洞 [J].電子技術(shù)與軟件工程,2017(13):263.
[3] AUSTIN T M,BREACH S E,SOHI G S. Efficient detection of all pointer and array access errors [J].ACM SIGPLAN Notices,1994,29(6):290-301.
[4] 嚴(yán)俊琦,陳哲,黃志球.C程序內(nèi)存安全的運行時檢測方法研究和實現(xiàn) [J].小型微型計算機(jī)系統(tǒng),2017,38(10):2358-2362.
[5] 李文明,陳哲,李緒蓉,等.C程序數(shù)組越界的運行時驗證技術(shù)研究與實現(xiàn) [J].計算機(jī)工程與應(yīng)用,2015,51(11):190-195+211.
[6] MA R,Chen L K,Hu C Z,et al. A dynamic detection method to C/C++ programs memory vulnerabilities based on pointer analysis [C]//2013 IEEE 11th International Conference on Dependable, Autonomic and Secure Computing. Chengdu:IEEE,2013:52-57.
[7] XU W,DUVARNEY D C,SEKAR R. An efficient and backwards-compatible transformation to ensure memory safety of C programs [C]//ACM SIGSOFT twelfth international symposium on Foundations of software engineering. Newport Beach:Stony Brook University,2004:117-126.
[8] STEPANOV E,SEREBRYANY K. MemorySanitizer: Fast detector of uninitialized memory use in C++ [C]//2015 IEEE/ACM International Symposium on Code Generation and Optimization (CGO). San Francisco:IEEE,2015:46-55.
[9] SEREBRYANY K,BRUENING D,POTAPENKO A,et al. Addresssanitizer: A fast address sanity checker [C]//Usenix Conference on Technical Conference. USENIX Association,2012:309-318.
[10] NAGARAKATTE S,ZHAO J,MARTIN M M K,et al. SoftBound: Highly compatible and complete spatial memory safety for C [C]//Proceedings of the 2009 ACM SIGPLAN Conference on Programming Language Design and Implementation. Dublin:ACM,2009:245-258.
[11] Frascaroli J,Brivio S,Covi E,et al. Evidence of soft bound behaviour in analogue memristive devices for neuromorphic computing [J].Scientific reports,2018,8(1):1-12.
[12] Nethercote N,Seward J. Valgrind: a framework for heavyweight dynamic binary instrumentation [J].ACM Sigplan notices,2007,42(6):89-100.
[13] Nethercote N,Seward J. Valgrind: A program supervision framework [J].Electronic notes in theoretical computer science,2003,89(2):44-66.
作者簡介:張琦(1992—),男,漢族,江蘇連云港人,碩士研究生在讀,主要研究方向:軟件驗證;劉一辰(1999—),男,漢族,河北邢臺人,碩士研究生在讀,主要研究方向:軟件驗證。