999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

跨平臺(tái)內(nèi)存安全測試集設(shè)計(jì)①

2022-09-20 04:10:34沈思豪

沈思豪, 解 達(dá), 宋 威

1(中國科學(xué)院 信息工程研究所 信息安全國家重點(diǎn)實(shí)驗(yàn)室, 北京 100093)

2(中國科學(xué)院大學(xué)網(wǎng)絡(luò)空間安全學(xué)院, 北京 101408)

1 引言

內(nèi)存安全問題一直是安全領(lǐng)域中經(jīng)久不衰的問題[1]. 從緩沖區(qū)溢出漏洞的利用開始, 到現(xiàn)在返回導(dǎo)向編程技術(shù)(return oriented programming, ROP)[1,2]、數(shù)據(jù)導(dǎo)向編程技術(shù)(data oriented programming, DOP)[3]攻擊的應(yīng)用, 基于內(nèi)存安全問題的攻擊手段在不斷地更新迭代. 相應(yīng)的, 也不斷有內(nèi)存安全防御方案被提出. 早期的內(nèi)存安全防御方案大多基于軟件, 如棧幀守護(hù)者(stack canary)[4], Ccured[5]等, 這些方案雖然能夠達(dá)到較好的防御效果, 但是性能開銷較大. 所以這些方案鮮有被應(yīng)用于商業(yè)處理器架構(gòu)之上. 近幾年來, 隨著RISC-V等開源處理器架構(gòu)的興起, 陸續(xù)有新的硬件輔助內(nèi)存安全方案被提出. 硬件支持使得防御方案的性能開銷降低. 商業(yè)處理器架構(gòu)逐漸產(chǎn)生了接納硬件輔助安全方案的趨勢.

然而目前, 無論是在工業(yè)界還是學(xué)術(shù)界, 都缺少對(duì)處理器內(nèi)存安全性能進(jìn)行評(píng)估的測試集. 現(xiàn)有的測試集, 如RIPE[6], CBench[7]等, 雖然能夠在特定的內(nèi)存安全性質(zhì)上進(jìn)行測試, 但是難以系統(tǒng)全面地反映處理器的內(nèi)存安全狀況; 此外, 對(duì)于x86系列以外的指令集架構(gòu)的支持也不盡如人意.

因此, 設(shè)計(jì)一個(gè)系統(tǒng)的, 完善的, 跨平臺(tái)的, 可拓展性強(qiáng)的硬件內(nèi)存安全測試集就顯得尤為重要. 為了解決這個(gè)問題, 我們提出了一個(gè)可拓展的內(nèi)存安全測試集框架, 在該框架下給出了大小為160個(gè)測例的初始版本測試集. 受限于可用硬件資源, 我們僅在x86-64和RISC-V64兩種指令集的不同平臺(tái)上對(duì)測試集進(jìn)行了測試. 初始版本的測試集涵蓋了內(nèi)存的時(shí)間、空間安全性, 內(nèi)存訪問控制, 指針完整性和控制流完整性等幾個(gè)方面的安全特性.

本文工作可開源獲取, 初始版本測試集可以在GitHub上找到: https://github.com/comparch-security/cpu-sec-bench.

2 研究背景

2.1 內(nèi)存安全攻擊防御技術(shù)概述

內(nèi)存安全攻擊和防御手段其實(shí)處于相互競爭和相互促進(jìn)的關(guān)系中.

類似C/C++的編程語言在底層實(shí)現(xiàn)中缺乏內(nèi)存安全支持, 導(dǎo)致使用C/C++語言編寫的大量應(yīng)用程序和動(dòng)態(tài)庫中包含緩沖區(qū)溢出、指針釋放后使用(useafter-free, UAF)等內(nèi)存時(shí)間和空間安全性漏洞.

代碼注入攻擊利用上述漏洞, 將預(yù)先構(gòu)造好的惡意代碼寫入堆棧等用戶數(shù)據(jù)區(qū)中, 將棧幀中保存的返回地址等代碼指針的值覆蓋為惡意代碼起始地址, 從而實(shí)現(xiàn)惡意的代碼執(zhí)行.

代碼注入攻擊要求攻擊者能夠?qū)阂獯a寫入用戶的可寫數(shù)據(jù)區(qū), 劫持程序的控制流指向惡意代碼, 保證惡意代碼能夠執(zhí)行. 針對(duì)這些前提條件, 一些經(jīng)典的內(nèi)存安全防御方案被提出: 棧幀守護(hù)者[8]在函數(shù)返回時(shí)檢測棧幀是否被緩沖區(qū)溢出覆蓋, 阻止攻擊者劫持棧幀中保存的返回地址; 數(shù)據(jù)執(zhí)行保護(hù)(data execution prevention, DEP)設(shè)置頁面可寫不可執(zhí)行屬性, 將可執(zhí)行頁和可寫頁分開, 保證攻擊者即使成功將惡意代碼植入用戶可寫數(shù)據(jù)區(qū), 也無法將其作為代碼執(zhí)行; 地址空間隨機(jī)化(address space layout randomization, ASLR)通過使用位置無關(guān)代碼(place-independent code, PIC),在程序加載時(shí)將加載基地址隨機(jī)化, 達(dá)到將程序執(zhí)行期間的數(shù)據(jù)和代碼地址隱藏的目的.

由于上述方案特別是數(shù)據(jù)執(zhí)行保護(hù)與地址空間隨機(jī)化的性能開銷低, 防御效果顯著, 所以得到了大范圍部署. 直接的代碼注入攻擊幾乎失效了. 但攻擊者仍然能夠訪問和調(diào)用程序自身和動(dòng)態(tài)庫提供的數(shù)據(jù)和代碼. 更復(fù)雜的內(nèi)存安全攻擊手段被提出, 來繞過上述防御方案, 如返回導(dǎo)向編程技術(shù)、跳轉(zhuǎn)導(dǎo)向編程技術(shù)(jump-oriented programming, JOP)[9]、偽造對(duì)象導(dǎo)向編程技術(shù)(counterfeit-object oriented programming,COOP)[10]、數(shù)據(jù)導(dǎo)向編程技術(shù)等, 這些攻擊手段都有一個(gè)共同的特征, 即不注入外部代碼, 而是直接復(fù)用受害者程序和標(biāo)準(zhǔn)庫中的代碼完成攻擊. 此類攻擊稱為代碼復(fù)用攻擊.

返回導(dǎo)向編程技術(shù)是典型的代碼復(fù)用攻擊[11], 常用于構(gòu)造指令執(zhí)行序列, 完成對(duì)系統(tǒng)函數(shù)mprotect等的調(diào)用, 關(guān)閉數(shù)據(jù)執(zhí)行保護(hù). 跳轉(zhuǎn)導(dǎo)向編程技術(shù)類似于返回導(dǎo)向編程記錄, 但在技術(shù)細(xì)節(jié)上存在不同.

返回導(dǎo)向編程技術(shù)攻擊會(huì)改變程序的正??刂屏?控制流完整性保護(hù)(control flow integrity, CFI)[12]通過在程序的間接跳轉(zhuǎn)前插入驗(yàn)證代碼, 保證程序的所有間接跳轉(zhuǎn)都在程序編譯時(shí)靜態(tài)分析得到的控制流圖的范圍內(nèi). 根據(jù)控制流分析精度的不同, 控制流完整性保護(hù)具體可以分為細(xì)粒度和粗粒度兩類. 前者使用不同的特征值區(qū)分不同的合法跳轉(zhuǎn)地址; 后者則不對(duì)合法跳轉(zhuǎn)地址進(jìn)行區(qū)分.

傳統(tǒng)的控制流完整性保護(hù)實(shí)現(xiàn)通過二進(jìn)制分析完成, 重點(diǎn)保護(hù)間接跳轉(zhuǎn)指令, 但是并不對(duì)類型進(jìn)行檢查,無法對(duì)多態(tài)類對(duì)象的虛函數(shù)表指針提供保護(hù). 偽造對(duì)象導(dǎo)向編程技術(shù)利用了這一點(diǎn), 通過在用戶數(shù)據(jù)區(qū)偽造對(duì)象, 修改虛函數(shù)表指針, 復(fù)用其它多態(tài)類提供的虛函數(shù)表, 通過調(diào)用一系列虛函數(shù)完成攻擊.

偽造對(duì)象導(dǎo)向編程技術(shù)攻擊無法通過簡單的二進(jìn)制控制流分析實(shí)現(xiàn)的控制流完整性保護(hù)進(jìn)行檢測, 需要結(jié)合類型實(shí)現(xiàn)控制流完整性保護(hù)進(jìn)行防御. 典型的防御方案如代碼指針完整性保護(hù)(code pointer integrity,CPI)[13], 指針標(biāo)記(pointer tagging), 指針審計(jì)(pointer authentication)等. 在x86架構(gòu)下的GCC提供了虛函數(shù)表驗(yàn)證(vtable verification, VTV)[14]特性, 用于驗(yàn)證虛函數(shù)調(diào)用的正確性, 但是默認(rèn)沒有被GCC開啟.

數(shù)據(jù)導(dǎo)向編程技術(shù)[3]通過修改控制程序分支執(zhí)行的關(guān)鍵數(shù)據(jù)來進(jìn)行攻擊, 達(dá)到劫持程序控制流的目的.對(duì)于一些涉及敏感系統(tǒng)調(diào)用的程序, 數(shù)據(jù)導(dǎo)向編程技術(shù)攻擊同樣可以完成關(guān)閉數(shù)據(jù)執(zhí)行保護(hù)的操作.

應(yīng)對(duì)上述高級(jí)攻擊的內(nèi)存安全防御方案一般有兩種實(shí)現(xiàn)方式. 一種使用純軟件方式實(shí)現(xiàn), 主要在標(biāo)準(zhǔn)庫、內(nèi)核和編譯器的層面進(jìn)行安全增強(qiáng), 很少或不依賴硬件提供支持, 導(dǎo)致性能開銷過高, 難以被大范圍部署. 例如, 代碼指針完整性保護(hù)雖然能夠防御大部分的代碼復(fù)用攻擊, 但是由于插入的驗(yàn)證代碼過多, 導(dǎo)致性能開銷過高, 一直沒有被主流編譯器(GCC, LLVM)采納.

另一種方式使用硬件輔助的方法提供內(nèi)存安全支持. 相較于純軟件的實(shí)現(xiàn)方式, 硬件輔助的實(shí)現(xiàn)方式能夠?qū)Π踩桨高M(jìn)行加速, 大幅降低安全方案實(shí)現(xiàn)的硬件開銷. 典型的硬件輔助防御方案如Intel的Intel內(nèi)存保護(hù)拓展(memory protection extension, MPX), Intel 控制流保護(hù)拓展(controlflow enforcement technology,CET), ARM公司在ARM v8.3-A中增加的Arm指針審計(jì)(pointer authentication, PA), ARM v8.5-A中增加的內(nèi)存標(biāo)簽拓展(memory tagging extension, MTE).

2.2 學(xué)術(shù)研究中硬件安全測試現(xiàn)狀

為了比較不同處理器提供的內(nèi)存安全性, 我們需要一套測試集. 這套測試集: 1)相對(duì)完善, 能夠量化處理器的內(nèi)存安全性; 2)可移植性強(qiáng), 能夠在多個(gè)處理器平臺(tái)上進(jìn)行測試.

然而, 現(xiàn)在學(xué)術(shù)界普遍使用的測試集大多只關(guān)注內(nèi)存安全的某個(gè)特定方面, 缺乏對(duì)內(nèi)存安全的整體把握和評(píng)估. 以經(jīng)典的內(nèi)存安全測試集RIPE為例: RIPE測試集[6]是一系列緩沖區(qū)溢出攻擊的集合. 它應(yīng)用廣泛, 常被用于測試控制流完整性保護(hù)防御方案. 每個(gè)測例都受5個(gè)變量控制: 緩沖區(qū)溢出位置、受攻擊的代碼指針類型、溢出攻擊的類型、惡意代碼和攻擊使用的函數(shù). RIPE使用枚舉窮盡各個(gè)變量組合的方法對(duì)緩沖區(qū)溢出做了相對(duì)完善的測試, 但是對(duì)于緩沖區(qū)溢出以外的漏洞涉及不多, 所以不適合作為一個(gè)完善的處理器內(nèi)存安全測試集.

在上述觀察的基礎(chǔ)上, 我們提出了一種處理器內(nèi)存安全測試框架, 并開源了一個(gè)基于該框架的內(nèi)存安全測試集. 內(nèi)存安全測試集的初始版本包括160項(xiàng)測例, 覆蓋了內(nèi)存的時(shí)空安全性(spatial and temporal safety)、內(nèi)存訪問控制、指針完整性、控制流完整性等方面. 不同類型的漏洞及其相應(yīng)的防御方案分別由對(duì)應(yīng)的測例進(jìn)行評(píng)測. 測試集已經(jīng)在x86-64和RISCV64兩種指令集架構(gòu)的幾個(gè)不同平臺(tái)上進(jìn)行了評(píng)估.

2.3 安全假設(shè)

為了將測試范圍限制在內(nèi)存安全上, 我們作如下假設(shè): 1)攻擊者能夠控制用戶程序的輸入, 惡意利用程序的內(nèi)存安全漏洞如注入惡意代碼; 2)用戶程序包含可以被攻擊者所利用的內(nèi)存漏洞, 攻擊者可以利用漏洞實(shí)現(xiàn)對(duì)程序任意地址的讀寫; 3)我們還假設(shè)攻擊者的目的是攻擊用戶程序空間內(nèi)的數(shù)據(jù), 而不是內(nèi)核數(shù)據(jù); 4)此外, 我們也不考慮側(cè)信道攻擊, 如緩存?zhèn)刃诺馈⑺矐B(tài)執(zhí)行攻擊等.

3 測試框架設(shè)計(jì)

3.1 測試對(duì)象

處理器內(nèi)存安全測試集以平臺(tái)為對(duì)象進(jìn)行測試.平臺(tái)定義為測試集可以運(yùn)行的環(huán)境. 它包括被測處理器以及運(yùn)行于其上的操作系統(tǒng). 操作系統(tǒng)包括一個(gè)內(nèi)核以及若干運(yùn)行時(shí)庫.

3.2 測試范圍

測試集假設(shè): 內(nèi)存安全是一系列內(nèi)存安全性質(zhì)的集合; 所有的內(nèi)存漏洞和漏洞利用都是由于對(duì)某些內(nèi)存安全性質(zhì)缺少檢查, 使得內(nèi)存中的值被惡意泄露或篡改. 根據(jù)上述假設(shè), 對(duì)內(nèi)存安全的評(píng)估可以被細(xì)化為一系列對(duì)內(nèi)存安全性質(zhì)的測試, 測試這些內(nèi)存安全性質(zhì)是否能夠被惡意利用. 如果一項(xiàng)測例成功完成執(zhí)行,說明平臺(tái)對(duì)該測例對(duì)應(yīng)的內(nèi)存安全性質(zhì)缺少檢查.通過的測例數(shù)和被安全檢查攔截的測例分布, 可以反映系統(tǒng)整體的內(nèi)存安全性.

測試集主要關(guān)注那些能夠被硬件輔助安全方案保護(hù)的內(nèi)存安全性質(zhì). 對(duì)于利用內(nèi)存漏洞展開的攻擊, 我們分析該攻擊破壞或利用了哪些內(nèi)存安全性質(zhì), 而不關(guān)注攻擊本身.

以緩沖區(qū)溢出攻擊為例. 緩沖區(qū)溢出攻擊是一種越過緩沖區(qū)邊界對(duì)值進(jìn)行修改的行為. 該行為破壞了緩沖區(qū)不應(yīng)該越界訪問的內(nèi)存安全性質(zhì). PUMP[15],AArch64 Address Sanitizer等硬件輔助的安全機(jī)制能夠?qū)彌_區(qū)越界訪問提供防護(hù). 所以, 對(duì)于緩沖區(qū)溢出,測試集測試幾類常見的訪問越界行為, 這些行為可能不構(gòu)成完整的攻擊. 這些行為如果被攔截, 則說明平臺(tái)保護(hù)了緩沖區(qū)不應(yīng)越界訪問的性質(zhì).

然而, 由于測試集本身也是軟件, 也需要在系統(tǒng)環(huán)境下運(yùn)行, 所以單憑測試集本身難以區(qū)分一個(gè)內(nèi)存檢查到底是通過硬件方式還是純軟件方式實(shí)現(xiàn)的. 所以需要保證測試覆蓋的內(nèi)存檢查是由平臺(tái)而不是第三方安全軟件實(shí)現(xiàn)的. 例如, 二進(jìn)制翻譯技術(shù)和專用的內(nèi)核安全補(bǔ)丁也能提供內(nèi)存安全防護(hù), 但由于它們使用純軟件方式實(shí)現(xiàn), 所以應(yīng)當(dāng)排除在測試范圍之外.

3.3 測例分布

測例主要覆蓋內(nèi)存的空間安全性、時(shí)間安全性、訪問控制、指針完整性、控制流完整性等5個(gè)方面.

3.3.1 空間安全性

空間安全性指內(nèi)存訪問總是落在正確的數(shù)據(jù)邊界和程序的可見域內(nèi)的性質(zhì). 任何數(shù)據(jù)邊界外或是可見域外的訪問都是不安全的. 典型的破壞空間安全性的攻擊是緩沖區(qū)溢出攻擊. 它是對(duì)緩沖區(qū)的越界訪問. 除了緩沖區(qū)以外, 棧幀、動(dòng)態(tài)分配對(duì)象、全局變量、只讀數(shù)據(jù)等均存在越界訪問的風(fēng)險(xiǎn).

緩沖區(qū)溢出按照溢出方向可以分為上溢和下溢;按照緩沖區(qū)位置可以分為堆上溢出和棧幀溢出. 噴射攻擊是溢出攻擊的一種特殊應(yīng)用, 它將溢出位置和目標(biāo)位置之間的全部內(nèi)存都進(jìn)行填充, 插入指向目標(biāo)位置的跳轉(zhuǎn)代碼, 降低控制流劫持的難度.

對(duì)于緩沖區(qū)溢出的檢測和防御方法包括內(nèi)存檢測器(address sanitizer, Asan)[16]、內(nèi)存標(biāo)記[17]和重型指針(fat pointer)[18]; 對(duì)于棧幀越界訪問, 使用重型指針在棧幀粒度上保持?jǐn)?shù)據(jù)完整性[19]、在棧幀之間填充字節(jié)[20]、在棧幀粒度進(jìn)行數(shù)據(jù)隔離[21]都是有效的防御手段; 對(duì)于堆越界訪問, 部分防御方案將陷阱數(shù)據(jù)填充在對(duì)象之間[22], 或者在對(duì)象粒度上進(jìn)行邊界檢查.

測試集的空間安全性測例共98項(xiàng), 主要使用兩種方式構(gòu)造緩沖區(qū)越界訪問: 1)通過合法的緩沖區(qū)指針和越界的地址偏移; 2)修改合法的緩沖區(qū)指針指向界外位置. 測試集對(duì)棧上、堆上、全局變量、只讀數(shù)據(jù)中的越界訪問都進(jìn)行了測試.

3.3.2 時(shí)間安全性

時(shí)間安全性指內(nèi)存中的數(shù)據(jù)訪問只發(fā)生在數(shù)據(jù)的生命周期之內(nèi). 任何發(fā)生在程序生命周期之前(未初始化數(shù)據(jù))和之后(釋放后使用)的訪問都是不安全的. 時(shí)間安全性的測例只關(guān)心一個(gè)生命周期外的訪問是否會(huì)發(fā)生, 不會(huì)針對(duì)具體的內(nèi)存分配算法進(jìn)行測試.

釋放后使用相關(guān)的漏洞主要包括空懸指針(dangling pointer), 未初始化變量等. 在堆上和棧上的空懸指針都會(huì)為程序帶來較大的安全隱患.

應(yīng)對(duì)空懸指針的防御方案包含空懸指針歸零[23]、解引用前檢查空懸指針[24]、阻止分配器在被釋放對(duì)象地址進(jìn)行重分配[25]、阻止未初始化數(shù)據(jù)訪問、細(xì)粒度??臻g隨機(jī)化[26]、內(nèi)存標(biāo)記等.

與時(shí)間安全性相關(guān)的測試共有13項(xiàng), 主要檢測棧上或堆上的數(shù)據(jù)在棧幀或?qū)ο蟊会尫藕竽芊癖豢諔抑羔樌^續(xù)訪問. 此外, 還檢查平臺(tái)是否具有保證相同類型的對(duì)象在相同的內(nèi)存地址不被重新分配、函數(shù)每次調(diào)用時(shí)動(dòng)態(tài)變化棧幀結(jié)構(gòu)等性質(zhì).

3.3.3 訪問控制

訪問控制性質(zhì)指限制了攻擊者內(nèi)存訪問能力的性質(zhì). 主要用來防御信息泄露攻擊. 程序的函數(shù)體代碼、全局偏移量表(global offset table, GOT)都是潛在的攻擊目標(biāo). 攻擊者在運(yùn)行時(shí)讀取程序的函數(shù)體代碼, 檢索可能成為gadget的代碼片段, 用以構(gòu)造代碼復(fù)用攻擊.

全局偏移量表用于程序動(dòng)態(tài)鏈接共享庫時(shí)檢索符號(hào). 由于全局偏移量表表項(xiàng)在運(yùn)行時(shí)動(dòng)態(tài)更新, 所以需要存儲(chǔ)在可寫頁上. 攻擊者可以通過讀取全局偏移量表表項(xiàng)獲取動(dòng)態(tài)庫函數(shù)在內(nèi)存中的地址, 造成信息泄露. 攻擊者也可以通過修改全局偏移量表來劫持庫函數(shù).

針對(duì)上述攻擊, 主要的防御技術(shù)包括地址空間隨機(jī)化, 防止攻擊者讀取可執(zhí)行頁的代碼隨機(jī)化、可讀不可執(zhí)行[27]等. 測試集的訪問控制測例共3項(xiàng), 也圍繞這些防御技術(shù)展開, 主要檢查地址空間隨機(jī)化是否有效, 函數(shù)體代碼是否可讀, 以及全局偏移量表特定表項(xiàng)是否可讀等.

3.3.4 指針完整性

典型的控制流劫持攻擊和防御手段經(jīng)常圍繞指針展開. 攻擊的第1階段修改保存敏感數(shù)據(jù)的指針, 破壞了指針完整性; 第2階段使用被修改的指針劫持控制流, 破壞了控制流完整性.

指針完整性測例主要關(guān)注保存敏感數(shù)據(jù)的指針的安全性. 敏感數(shù)據(jù)指針包括函數(shù)指針、虛函數(shù)表指針和全局偏移量表.

函數(shù)指針通??煽截惖豢尚薷? 進(jìn)行算數(shù)運(yùn)算的情況非常罕見. 函數(shù)指針一般通過指針審計(jì)和指針標(biāo)記[13]進(jìn)行保護(hù). 虛函數(shù)表指針指向一張函數(shù)指針表,其中每個(gè)表項(xiàng)指向類型對(duì)應(yīng)的虛函數(shù). 對(duì)虛函數(shù)表指針的保護(hù)方案包括代碼指針完整性保護(hù)[13]、GCC VTV等.

測試集的指針完整性測例共5項(xiàng), 主要檢測平臺(tái)是否允許函數(shù)指針拷貝和算術(shù)運(yùn)算, 是否允許對(duì)虛函數(shù)表指針進(jìn)行讀取和修改、是否允許對(duì)全局偏移量表進(jìn)行修改等.

3.3.5 控制流完整性

控制流體現(xiàn)了程序動(dòng)態(tài)執(zhí)行時(shí)指令間邏輯上的先后順序. 通過代碼指針調(diào)用完成的控制流跳轉(zhuǎn)稱為前向控制流; 通過返回地址完成的控制流跳轉(zhuǎn)稱為后向控制流. 前向控制流完整性指保護(hù)代碼指針解引用到合法的地址; 后向控制流完整性指保護(hù)返回地址不被惡意篡改.

控制流完整性相關(guān)的攻擊方式包括代碼注入攻擊、代碼復(fù)用攻擊等, 對(duì)于使用多態(tài)的程序還包括虛函數(shù)表劫持攻擊. 測試集的控制流完整性測例共41項(xiàng),主要圍繞這些攻擊的典型防御方案如數(shù)據(jù)執(zhí)行保護(hù),控制流完整性保護(hù)等進(jìn)行測試.

3.4 測例構(gòu)造

測試集的整體架構(gòu)如圖1所示. 測試樣例由兩部分組成: 平臺(tái)無關(guān)的測試邏輯, 與平臺(tái)相關(guān)的支持庫.

圖1 內(nèi)存安全測試集整體框架圖

每個(gè)測例為測試特定內(nèi)存安全性質(zhì)的C++程序;若某條性質(zhì)對(duì)應(yīng)的安全檢查缺失, 測例可以利用該漏洞完成測試邏輯并返回零值, 表示漏洞被成功利用; 否則測例返回非零值并提示測試失敗.

整個(gè)測試集的運(yùn)行通過測試驅(qū)動(dòng)控制. 測試驅(qū)動(dòng)使用指定的編譯選項(xiàng)對(duì)測例進(jìn)行編譯, 運(yùn)行測例并統(tǒng)計(jì)測例的運(yùn)行結(jié)果, 得到測例通過數(shù)量的量化數(shù)據(jù).

測例中利用漏洞的惡意行為常常以匯編代碼的形式實(shí)現(xiàn). 這是為了防止編譯器優(yōu)化掉惡意行為. 這些匯編代碼在平臺(tái)相關(guān)的支持庫中. 測試邏輯是使用平臺(tái)無關(guān)的方式編寫的; 需要使用惡意代碼的部分通過調(diào)用平臺(tái)支持庫來完成.

測例的可移植性通過測試邏輯與支持庫的劃分實(shí)現(xiàn). 二者之間通過宏的定義和調(diào)用產(chǎn)生聯(lián)系. 支持庫中的匯編代碼使用宏定義的方式組織; 測試邏輯通過引用宏定義完成調(diào)用. 不同平臺(tái)的支持庫對(duì)相同的宏名稱提供定義, 使用平臺(tái)特定的匯編代碼實(shí)現(xiàn)相同的動(dòng)作. 每個(gè)測例都會(huì)引用公共頭文件(include/assembly.hpp), 該文件對(duì)不同平臺(tái)支持庫的頭文件進(jìn)行了包裝,通過不同架構(gòu)的預(yù)定義宏進(jìn)行區(qū)分(如__x86_64、__riscv64), 編譯測試集時(shí)編譯器會(huì)根據(jù)預(yù)定義宏選擇正確架構(gòu)對(duì)應(yīng)的支持庫.

對(duì)于新增加的平臺(tái)或指令集架構(gòu), 只需要和其他支持庫對(duì)同樣的宏名稱進(jìn)行定義即可, 不需要修改測試邏輯; 對(duì)于新增加的測例, 需要將測試使用支持庫提供的宏實(shí)現(xiàn), 如果需要新增宏定義, 則需要在所有的支持庫中將對(duì)該宏進(jìn)行定義. 對(duì)于新的指令集架構(gòu)而言,目前只有約20個(gè)宏名稱需要被實(shí)現(xiàn). 綜上所述, 測試集具有良好的可拓展性.

下面以控制流完整性的測例call-instruction-instack為例, 描述測例的代碼結(jié)構(gòu)和測試流程.

測例call-instruction-in-stack用來測試將棧上地址作為目標(biāo)地址的情況下, 函數(shù)調(diào)用是否能夠成功執(zhí)行.測試邏輯的主要代碼如代碼清單1所示. 其中assembly.hpp和signal.hpp均為平臺(tái)支持庫的公共頭文件. 頭文件assembly.hpp負(fù)責(zé)提供FORCE_NOINLINE、CALL_DAT、FUNC_MACHINE_CODE等宏的宏定義. 頭文件signal.hpp負(fù)責(zé)提供異常處理所需的接口代碼. 部分平臺(tái)在檢測到違反內(nèi)存安全規(guī)則的操作時(shí)會(huì)拋出異常,signal.hpp提供將這些異常捕獲并產(chǎn)生特定返回值的代碼.

代碼清單 1. call-instruction-in-stack的測試邏輯#include "include/assembly.hpp"#include "include/signal.hpp"int gv = 1;int FORCE_NOINLINE helper(const unsigned char* m) {CALL_DAT(m);return gv;}int main(){unsigned char m[] = FUNC_MACHINE_CODE;… //異常處理初始化代碼int rv = helper(m);… //異常處理收尾代碼exit(rv);}

宏FORCE_NOINLINE的作用是使強(qiáng)制被修飾函數(shù)不生成內(nèi)聯(lián)代碼, 原因是內(nèi)聯(lián)代碼在部分平臺(tái)上會(huì)影響測例測試邏輯的正確性; 宏CALL_DAT(addr)的作用是將addr作為目標(biāo)地址, 進(jìn)行函數(shù)調(diào)用; 宏FUNC_MACHINE_CODE的作用是模擬函數(shù)體代碼, 使得CALL_DAT宏產(chǎn)生的函數(shù)調(diào)用一旦成功執(zhí)行, 后續(xù)指令能夠正常返回或是產(chǎn)生特定異常并被main函數(shù)中異常捕獲邏輯捕獲, 使得測例能夠正常退出.

宏CALL_DAT的具體實(shí)現(xiàn)為C擴(kuò)展內(nèi)嵌匯編代碼, 所以不同的指令集架構(gòu)上, 實(shí)現(xiàn)各不相同. 在x86-64指令集架構(gòu)上其實(shí)現(xiàn)如代碼清單2所示, 在RISCV64指令集架構(gòu)上其實(shí)現(xiàn)如代碼清單3所示.

代碼清單 2. CALL_DAT宏的RISC-V64架構(gòu)實(shí)現(xiàn)#define CALL_DAT(ptr) asm volatile( "jalr ra, %0, 0;" : : "r"(ptr) : "ra" )代碼清單 3. CALL_DAT宏的x86-64架構(gòu)實(shí)現(xiàn)#define CALL_DAT(ptr) asm volatile( "call *%0;" : : "r" (ptr) )

如果需要將本測例移植到ARM AArch64架構(gòu), 則只需要在ARM AArch64指令集架構(gòu)的平臺(tái)支持庫和頭文件中實(shí)現(xiàn)對(duì)FORCE_NOINLINE、CALL_DAT和FUNC_MACHINE_CODE這3個(gè)宏的定義即可.

測例測試邏輯的核心部分在helper函數(shù). 如果helper函數(shù)中的CALL_DAT宏成功執(zhí)行, FUNC_MACHINE_CODE將會(huì)和main函數(shù)中的異常處理代碼結(jié)合, 將rv的值設(shè)置為0. 測例將以返回值0退出,表示測試通過. 如果CALL_DAT宏的執(zhí)行拋出異常,則main函數(shù)中的異常處理代碼會(huì)將拋出的異常轉(zhuǎn)換為非零返回值-1并退出程序.

4 測試結(jié)果及分析

4.1 測試平臺(tái)

對(duì)于x86-64架構(gòu), 我們使用一臺(tái)較舊的Intel i7-3770 CPU搭配Ubuntu 16.04操作系統(tǒng), 和一臺(tái)較新的Intel Xeon 8280 CPU搭配Ubuntu 18.04操作系統(tǒng)進(jìn)行測試.

對(duì)于RISC-V64架構(gòu), 我們使用SiFive公司的HiFive Unleashed和HiFive Unmatched兩款開發(fā)板進(jìn)行測試, 兩塊開發(fā)板分別基于SiFive公司的u540和u740 CPU, 操作系統(tǒng)均為SiFive公司提供的預(yù)編譯OpenEmbedded操作系統(tǒng).

我們?cè)趚86-64和 RISC-V64兩個(gè)ISA架構(gòu)的4個(gè)平臺(tái)上應(yīng)用測試集進(jìn)行了測試. 平臺(tái)列表如表1所示.

表1 內(nèi)存安全測試集運(yùn)行平臺(tái)參數(shù)

4.2 測試結(jié)果

4.2.1 不同平臺(tái)間安全性對(duì)比

為了保持一致性, 我們?cè)诓煌脚_(tái)上統(tǒng)一使用操作系統(tǒng)提供的GNU g++編譯器, 使用相同的編譯選項(xiàng)“-O2 -std=c++11 -Wall”進(jìn)行編譯. 測試集結(jié)果的概要如表2所示.

表2 不同平臺(tái)成功執(zhí)行測試樣例數(shù)

時(shí)間安全性: Intel Xeon 8280、HiFive Unleashed、HiFive Unmatched平臺(tái)上, 部分堆上的釋放后使用相關(guān)測例運(yùn)行失敗. Intel i7-3770平臺(tái)全部測例運(yùn)行成功.說明除了Intel i7-3770平臺(tái)外, 其他各被測平臺(tái)都具有一定的內(nèi)存時(shí)間安全性防御能力. 通過調(diào)查原因發(fā)現(xiàn),這些平臺(tái)使用了較新版本的GLIBC. 后者采用了新的內(nèi)存分配算法, 在同一片內(nèi)存區(qū)域釋放后和分配前插入了垃圾內(nèi)容, 阻止了釋放后信息泄露以及偽造未初始化變量對(duì)象攻擊. 不過新的算法仍然能夠被強(qiáng)制在同一塊內(nèi)存區(qū)域重新分配相同類型的對(duì)象, 一些使用空懸指針的釋放后使用攻擊仍然有效. 此外, 各個(gè)被測平臺(tái)對(duì)棧上的釋放后使用同樣缺乏有效的安全檢查.

指針完整性: 在各個(gè)被測平臺(tái)上, 讀寫代碼指針和虛函數(shù)表指針的測例全部成功執(zhí)行. 雖然編譯器在編譯階段給出了指針?biāo)銛?shù)運(yùn)算的警告, 但是指針?biāo)銛?shù)運(yùn)算測例在各個(gè)平臺(tái)仍然能夠成功執(zhí)行. 修改全局偏移量表表項(xiàng)的測例在Intel Xeon 8280平臺(tái)上執(zhí)行失敗,但在其他平臺(tái)上成功執(zhí)行. 說明4個(gè)被測平臺(tái)中, 只有Intel Xeon 8280平臺(tái)默認(rèn)提供了部分指針完整性檢查.該檢查來自重定位只讀保護(hù)(relocation read-only,RELRO), 大多數(shù)Linux發(fā)行版都默認(rèn)提供了部分重定位只讀保護(hù). 但是在HiFive Unmatched和HiFive Unleashed兩個(gè)平臺(tái)上重定位只讀保護(hù)并沒能覆蓋庫函數(shù)的入口.

訪問控制: 檢測發(fā)現(xiàn)Intel i7-3770平臺(tái)的地址空間隨機(jī)化測例成功執(zhí)行. 其他各被測平臺(tái)除了地址空間隨機(jī)化測例以外其余測例都成功執(zhí)行. 說明被測平臺(tái)中大部分都默認(rèn)開啟了地址空間隨機(jī)化保護(hù), 但是缺乏對(duì)信息泄露的進(jìn)一步防御. 分析原因發(fā)現(xiàn), Intel i7-3770平臺(tái)編譯器默認(rèn)的編譯選項(xiàng)不支持生成位置無關(guān)代碼, 導(dǎo)致對(duì)用戶程序的地址空間隨機(jī)化無法使用. 增加“-pie -fPIE”選項(xiàng)后地址空間隨機(jī)化相關(guān)測例執(zhí)行失敗, 地址空間隨機(jī)化保護(hù)成功開啟.

空間安全性: 在4個(gè)被測平臺(tái)上, 所有98個(gè)測例都成功完成了測試. 說明被測平臺(tái)默認(rèn)提供的安全防護(hù)中缺乏對(duì)內(nèi)存越界訪問的安全檢查. 軟件上常使用address sanitizer來檢測越界訪問, 但是性能代價(jià)太高,只適合在開發(fā)階段使用, 無法部署到產(chǎn)品中. 硬件拓展如CHERI[28]、PUMP[15]等雖然實(shí)現(xiàn)了對(duì)越界訪問的檢查, 但是是以修改系統(tǒng)ABI、增加硬件開銷和性能開銷為代價(jià)的.

控制流完整性: 對(duì)于后向控制流劫持相關(guān)的測例,與返回導(dǎo)向編程技術(shù)相關(guān)的測例都成功執(zhí)行; 代碼注入攻擊的測例悉數(shù)被數(shù)據(jù)執(zhí)行保護(hù)攔截. 對(duì)于前向控制流劫持, 除了代碼注入攻擊的測例被數(shù)據(jù)執(zhí)行保護(hù)攔截, 其他類型攻擊相關(guān)的測例都成功執(zhí)行. 對(duì)于虛函數(shù)表保護(hù), 替換虛函數(shù)表、偽造虛函數(shù)表的相關(guān)測例均成功執(zhí)行. 對(duì)部分使用新的內(nèi)存分配算法的平臺(tái), 虛函數(shù)指針復(fù)用攻擊相關(guān)的測例執(zhí)行失敗, 調(diào)查原因發(fā)現(xiàn), 新的內(nèi)存分配算法在釋放對(duì)象時(shí)清零了虛函數(shù)表指針. 上述被測平臺(tái)都具有一定的控制流完整性防御能力.

總的來說, 在各個(gè)被測平臺(tái)上, 由默認(rèn)配置提供的安全防護(hù)并無太大區(qū)別. 各平臺(tái)默認(rèn)都沒有對(duì)空間安全性提供有效的保護(hù); 在HiFive Unleashed和HiFive Unmatched平臺(tái)上由于配套的工具鏈和運(yùn)行時(shí)庫增加了安全防護(hù), 所以提供了更好的時(shí)間安全性保護(hù). 地址空間隨機(jī)化和數(shù)據(jù)執(zhí)行保護(hù)雖然為各平臺(tái)提供了一定的內(nèi)存安全防護(hù)能力, 但覆蓋面較窄, 只能限制在特定的幾項(xiàng)內(nèi)存安全性質(zhì)上.

4.2.2 不同編譯器與編譯選項(xiàng)間對(duì)比

編譯器不同的編譯選項(xiàng)也提供了部分安全防護(hù).在Intel Xeon 8280平臺(tái)上, 使用GCC 10.3.0和GLIBC 2.32對(duì)不同的編譯選項(xiàng)進(jìn)行了測試. 為了測試LLVM提供的控制流完整性保護(hù)防御機(jī)制, 也將LLVM13在Intel Xeon 8280平臺(tái)上進(jìn)行了測試.

很可惜, 由于工具鏈移植仍然不完整, RISC-V的GCC和LLVM沒有提供對(duì)VTV和CFI的支持, RISCV架構(gòu)的address sanitizer無法正常工作, 剩余的可用內(nèi)存安全選項(xiàng)測試得到的結(jié)果差別不大, 對(duì)判斷RISCV架構(gòu)平臺(tái)的內(nèi)存安全性意義不大, 所以我們將只對(duì)Intel Xeon 8280平臺(tái)的測試結(jié)果進(jìn)行討論.

我們按照功能將編譯器提供的安全方面的編譯選項(xiàng)分為幾組, 如表3所示.

表3 內(nèi)存安全相關(guān)不同編譯選項(xiàng)組

下面對(duì)表3中的選項(xiàng)組進(jìn)行解釋.

默認(rèn)選項(xiàng): 只要求-O2優(yōu)化, 其他為編譯器默認(rèn)選項(xiàng); RELRO: 開啟對(duì)全局偏移量表的全面保護(hù); 棧保護(hù):通過在棧中插入canary實(shí)現(xiàn)棧覆寫保護(hù)(stack smashing protection); VTV: GCC支持的虛函數(shù)表驗(yàn)證特性,用于應(yīng)對(duì)偽造對(duì)象導(dǎo)向編程技術(shù)攻擊; CFI: LLVM支持的前向控制流攻擊防御機(jī)制; 全部防護(hù): 對(duì)編譯器應(yīng)用上述支持的所有編譯選項(xiàng); Asan: 開啟動(dòng)態(tài)address sanitizer; 無防護(hù): 關(guān)閉包括數(shù)據(jù)執(zhí)行保護(hù)在內(nèi)的所有防護(hù), 包括內(nèi)核提供的地址空間隨機(jī)化等.

在默認(rèn)選項(xiàng)下, Intel Xeon 8280平臺(tái)使用GCC 10.3的通過測例數(shù)為142, 與使用平臺(tái)默認(rèn)的編譯工具相比, 全局偏移量表篡改可行性的測例通過, 但是有4個(gè)堆上釋放后使用的測例失敗, 原因是采用了新的GLIBC庫. 使用LLVM通過的測例數(shù)同樣為142, 不過由于LLVM生成的代碼默認(rèn)不開啟PIE選項(xiàng), 并且在編譯時(shí)不允許代碼指針?biāo)阈g(shù)運(yùn)算, 所以具體成功執(zhí)行的測例稍有區(qū)別.

在RELRO選項(xiàng)下, Intel Xeon 8280平臺(tái)下GCC編譯通過測例數(shù)減少了1, LLVM編譯通過測例數(shù)減少了2. 可見開啟RELRO選項(xiàng)對(duì)測試集涉及的內(nèi)存安全漏洞并不敏感.

測試結(jié)果如表4所示.

表4 Intel Xeon 8280平臺(tái)下不同編譯選項(xiàng)組測試集編譯運(yùn)行通過測例數(shù)

開啟棧保護(hù)選項(xiàng)下, Intel Xeon 8280平臺(tái)下對(duì)測試集通過測例數(shù)幾乎沒有任何影響, 因?yàn)榇蠖鄶?shù)返回導(dǎo)向編程技術(shù)攻擊都可以定位返回地址保存位置, 并在不觸碰canary的情況下能夠修改返回地址. 失敗的測例為偽造棧幀攻擊相關(guān)的測例.

VTV選項(xiàng)下, Intel Xeon 8280平臺(tái)下6項(xiàng)偽造對(duì)象導(dǎo)向編程技術(shù)相關(guān)測例都測試失敗. 不過將虛函數(shù)表替換為子類、父類的行為仍然沒有被攔截.

CFI選項(xiàng)下, Intel Xeon 8280平臺(tái)下幾乎沒有提供任何安全增強(qiáng). 可能的原因是LLVM CFI要求在鏈接期間對(duì)所有的類定義都可見. 這需要使用靜態(tài)鏈接方式編譯. 而為了應(yīng)對(duì)編譯器優(yōu)化策略, 所有可執(zhí)行文件均以動(dòng)態(tài)鏈接方式鏈接. 這導(dǎo)致鏈接時(shí)分析將對(duì)虛函數(shù)表指針和函數(shù)指針的修改操作識(shí)別為了合法操作.

全部防護(hù)選項(xiàng)下, Intel Xeon 8280平臺(tái)下GCC編譯測試集共有26項(xiàng)測例失敗; LLVM編譯測試集共有22項(xiàng)測例失敗.

開啟Asan選項(xiàng)下, Intel Xeon 8280平臺(tái)下GCC編譯測試集通過的測例數(shù)減少為8. 通過的測例僅包括兩項(xiàng)訪問控制測試(read-func和read-GOT)以及6項(xiàng)棧上釋放后使用攻擊測例. LLVM編譯測試集通過的測例數(shù)減少為21. LLVM編譯測試集中, 返回導(dǎo)向編程技術(shù)和偽造對(duì)象導(dǎo)向編程技術(shù)攻擊相關(guān)的測例都測試失敗, 但是跳轉(zhuǎn)導(dǎo)向編程技術(shù)攻擊相關(guān)的測例仍然成功執(zhí)行, 全局偏移量表表項(xiàng)修改可行性的測例也成功執(zhí)行. 不過LLVM編譯測試集中所有的釋放后使用相關(guān)測例都測試失敗, 包括被GCC Asan漏掉的棧上釋放后使用攻擊測例.

無防護(hù)選項(xiàng)下, Intel Xeon 8280平臺(tái)下GCC編譯測試集僅有5項(xiàng)測例失敗. 失敗測例均為堆上釋放后使用攻擊測例. LLVM編譯測試集除了沒有編譯通過的代碼指針?biāo)阈g(shù)操作測例之外, 結(jié)果與GCC編譯測試集相同. 結(jié)合上述各點(diǎn), GCC編譯器與LLVM編譯器安全特性提供的內(nèi)存安全檢查大致相近, 只是在使用動(dòng)態(tài)鏈接類型定義時(shí)LLVM的CFI安全特性未能發(fā)揮有效作用, 相比于GCC稍遜一籌. 不過, LLVM測試集中關(guān)于代碼指針?biāo)銛?shù)運(yùn)算的測例沒有通過編譯, 而GCC測試集中只是給出了警告, 這也說明兩款編譯器對(duì)于內(nèi)存安全問題防護(hù)具有不同的側(cè)重點(diǎn). 兩款編譯器提供的address sanitizer攔截了絕大多數(shù)的內(nèi)存安全惡意行為, 說明大多數(shù)的內(nèi)存安全性質(zhì)都依賴于內(nèi)存的空間安全性.

5 討論與展望

5.1 相關(guān)工作

關(guān)于測試集, 早期的測試集主要用于測試計(jì)算機(jī)的計(jì)算性能. 19世紀(jì)70年代的LINPACK測試集用于測量計(jì)算機(jī)進(jìn)行線性代數(shù)數(shù)值計(jì)算的性能, 至今還用于超算的性能衡量中. Dhrystone[29]為衡量計(jì)算機(jī)普通整數(shù)運(yùn)算提供了性能指標(biāo); CoreMark專注于微控制器的性能測量; SPEC測試集[30]則用于性能更強(qiáng)的通用計(jì)算機(jī). PARSEC[31]則主要集中于衡量共享內(nèi)存和多線程應(yīng)用的性能.

在2005年, Kratkiewicz等[32]提出了使用構(gòu)造的小型緩沖區(qū)溢出攻擊測試現(xiàn)有的軟件防御方案.2006年, BASS[33]吸收了SPEC的思想, 將7個(gè)包含有不同種類內(nèi)存漏洞的測例綜合進(jìn)行安全性驗(yàn)證, 同時(shí)提供了一個(gè)框架用于自動(dòng)生成利用內(nèi)存漏洞攻擊. 據(jù)我們所知, BASS是最早的嘗試衡量計(jì)算機(jī)安全性的測試集; 然而該測試集的測試范圍只限定在幾個(gè)特殊的內(nèi)存空間漏洞上. RIPE[6]是當(dāng)前內(nèi)存安全領(lǐng)域應(yīng)用最為廣泛的安全測試集. 通過枚舉幾種攻擊方式的組合,RIPE能夠覆蓋850種緩沖區(qū)溢出攻擊和返回導(dǎo)向編程技術(shù)攻擊. 它也被用于衡量硬件輔助的控制流攻擊防御方案. 但是按照RIPE的方法覆蓋緩沖區(qū)溢出和返回導(dǎo)向編程技術(shù)攻擊就需要850項(xiàng)測例, 要對(duì)內(nèi)存安全進(jìn)行較全面的覆蓋可能難以實(shí)現(xiàn).

最近幾年出現(xiàn)了新的安全測試集設(shè)計(jì). CONFIRM[34]是最近提出的用于衡量不同控制流完整性防御方案的兼容性和可用性的安全測試集, 但是缺少對(duì)于安全性的評(píng)估. CBench[7]對(duì)控制流完整性防御方案的實(shí)際效果進(jìn)行評(píng)估, 采用與BASS類似的設(shè)計(jì), 共使用7個(gè)大類共18個(gè)包含漏洞的程序. 與本文工作相比, CBench使用完整的攻擊進(jìn)行測試, 而且集中在被測防御機(jī)制本身, 而不是實(shí)現(xiàn)這些機(jī)制的平臺(tái), 另外, CBench也不支持跨平臺(tái), 只能在x86-64架構(gòu)上運(yùn)行.

5.2 對(duì)其他主流指令集的支持

由于目前我們可用的平臺(tái)支持的指令集架構(gòu)只包括Intel x86-64和RISC-V64, 測試集目前僅在這兩個(gè)指令集上進(jìn)行了測試, 對(duì)于其他指令集架構(gòu)的支持正在進(jìn)行中. 未來計(jì)劃增加對(duì)ARM AArch64和龍芯/MIPS指令集架構(gòu)的支持.

5.3 對(duì)測試環(huán)境的討論

雖然主要測試目標(biāo)是處理器及相應(yīng)的指令集架構(gòu)的內(nèi)存安全水平, 但是測試集的執(zhí)行并不能脫離測試環(huán)境. 這也導(dǎo)致在測例不通過時(shí), 有時(shí)較難區(qū)分具體是處理器的硬件防御機(jī)制起了作用, 還是操作系統(tǒng)、編譯器或標(biāo)準(zhǔn)庫的軟件防御機(jī)制起了作用.

上述問題向測試集引入了操作系統(tǒng)、編譯器和標(biāo)準(zhǔn)庫等無關(guān)變量. 一種消除這些無關(guān)變量的方法是將所有被測平臺(tái)都強(qiáng)制安裝特定的操作系統(tǒng)、編譯器和相同版本的標(biāo)準(zhǔn)庫. 這種方法雖然在理論上可行, 但是實(shí)踐的難度很大. 如果將測試環(huán)境縮小到只包含內(nèi)核與命令行工具的最小系統(tǒng), 在嵌入式平臺(tái)上比較容易實(shí)現(xiàn), 但是在一般的服務(wù)器和PC機(jī)上安裝最小環(huán)境則比較困難. 如果將測試環(huán)境規(guī)定為特定版本的操作系統(tǒng)發(fā)行版(如Ubuntu), 那么這一發(fā)行版并非能夠被所有被測平臺(tái)支持, 如Mac M1和其他眾多嵌入式平臺(tái)等.

基于上述原因, 我們不強(qiáng)制所有平臺(tái)運(yùn)行特定的操作系統(tǒng)、編譯器和相同版本的標(biāo)準(zhǔn)庫, 而是默認(rèn)為某種發(fā)行版, 假定該發(fā)行版提供的測試環(huán)境足夠小. 我們將被測目標(biāo)的含義擴(kuò)大為硬件平臺(tái)及其支撐的運(yùn)行環(huán)境. 受控變量除了處理器和硬件平臺(tái)之外, 還包括平臺(tái)上運(yùn)行的操作系統(tǒng)、編譯器和標(biāo)準(zhǔn)庫.

為了消除增加受控變量帶來的影響, 保證能夠正確的分析測試的結(jié)果, 在測試集的構(gòu)成上, 測例盡量使用不同的非零返回值去標(biāo)注不同位置和不同原因造成的測試失敗, 從而為判斷生效的防御類型提供線索.

此外, 我們也使用現(xiàn)有的平臺(tái)對(duì)編譯器提供的內(nèi)存安全標(biāo)志選項(xiàng)進(jìn)行了討論, 分析了主流編譯器提供的內(nèi)存安全防護(hù)的有效性. 操作系統(tǒng)和標(biāo)準(zhǔn)庫這些變量對(duì)內(nèi)存安全防御的影響也可以通過配置不同的內(nèi)核安全功能、標(biāo)準(zhǔn)庫版本進(jìn)行評(píng)估. 不過限于篇幅和工作量的關(guān)系, 這些評(píng)估現(xiàn)在還沒有展開.

6 結(jié)論

我們?cè)O(shè)計(jì)了一套兼具綜合性和可移植性的內(nèi)存安全測試集框架. 初始的測試集包含160項(xiàng)測例, 覆蓋了內(nèi)存時(shí)空安全性、訪問控制、指針完整性和控制流完整性等幾個(gè)方面. 每一類漏洞及其相關(guān)的防御方案都被若干測例評(píng)估. 為驗(yàn)證可用性, 我們將測試集在Intel x86-64和RISC-V64指令集架構(gòu)上進(jìn)行了評(píng)估. 我們的評(píng)估結(jié)果顯示, 雖然地址空間隨機(jī)化和數(shù)據(jù)執(zhí)行保護(hù)等防御方案對(duì)被測平臺(tái)提供了部分內(nèi)存安全保護(hù),但大部分的內(nèi)存漏洞在部分處理器的默認(rèn)編譯器配置下仍然能夠被利用. 開啟額外的編譯器安全特性能夠抵御特定類型的內(nèi)存安全攻擊. 盡管address sanitizer作為調(diào)試工具不能用于生產(chǎn)環(huán)境中, 它在捕獲內(nèi)存安全攻擊上十分有效. 就相同平臺(tái)上的編譯器表現(xiàn)來看,LLVM和GCC能夠提供相近的內(nèi)存安全保護(hù), 兩者對(duì)內(nèi)存安全保護(hù)的側(cè)重各有不同.

致謝

感謝郭雄飛提供的HiFive Unleashed開發(fā)板以及中國科學(xué)院軟件研究所PLCT團(tuán)隊(duì)贈(zèng)與的HiFive Unmatched開發(fā)板. 兩套硬件設(shè)施對(duì)我們?cè)赗ISC-V架構(gòu)平臺(tái)上的測試起到了很大幫助.

主站蜘蛛池模板: 人妻无码中文字幕一区二区三区| 97青草最新免费精品视频| 伊人久久大香线蕉综合影视| 老司机久久99久久精品播放 | 亚洲色图综合在线| 91精品国产91久久久久久三级| 国产成人91精品免费网址在线| 91精选国产大片| AV不卡无码免费一区二区三区| 99久久亚洲精品影院| 国产一区二区三区免费| 亚洲欧美另类中文字幕| 色婷婷亚洲十月十月色天| 国产精品免费p区| 无码在线激情片| 国产成人91精品| 嫩草在线视频| 久久不卡精品| 福利小视频在线播放| 福利在线一区| 成人福利在线看| 国产一区二区三区在线观看视频| 亚洲免费福利视频| 色综合五月婷婷| aaa国产一级毛片| A级毛片无码久久精品免费| 永久在线播放| 青青久久91| 91久久夜色精品国产网站| 国产99久久亚洲综合精品西瓜tv| 久久久91人妻无码精品蜜桃HD| 欧美不卡在线视频| 欧美中文字幕第一页线路一| 99精品伊人久久久大香线蕉| 中文字幕一区二区视频| 日本免费新一区视频| 91小视频版在线观看www| 日韩在线2020专区| 91色在线视频| 免费大黄网站在线观看| 久久免费视频6| 中文字幕永久视频| 亚洲a级在线观看| 亚洲中文字幕23页在线| 亚洲男人天堂网址| 99久久精品免费观看国产| aa级毛片毛片免费观看久| a色毛片免费视频| 亚洲精品在线影院| 精品国产福利在线| 中国国产高清免费AV片| 五月激情综合网| 中日韩欧亚无码视频| 国产成人永久免费视频| 国产精品制服| 99在线小视频| 亚洲精品天堂在线观看| 亚洲第一精品福利| 夜夜操天天摸| 国产91熟女高潮一区二区| 久久99热66这里只有精品一| 亚洲精品777| 日韩美毛片| 欧美一级黄片一区2区| 久久久黄色片| 在线毛片免费| 内射人妻无套中出无码| 久久精品视频亚洲| 九九热视频精品在线| 亚洲天堂网在线播放| 在线观看91精品国产剧情免费| 免费看av在线网站网址| 草草影院国产第一页| 无码免费视频| 国产人妖视频一区在线观看| 亚洲第一色视频| 亚洲香蕉伊综合在人在线| 国产乱肥老妇精品视频| 色综合激情网| 亚洲人成色在线观看| 久久精品亚洲中文字幕乱码| 久久免费视频6|