高 慶 陳 靜 許 平 張世琨
1(北京大學(xué)軟件工程國家工程研究中心 北京 100871)2(北京北大軟件工程股份有限公司 北京 100080)3(中國電子科技集團(tuán)公司第三十研究所 成都 610041)
近年來,隨著計(jì)算機(jī)技術(shù)的發(fā)展,嵌入式系統(tǒng)在航空航天、核能、交通等安全攸關(guān)領(lǐng)域的應(yīng)用越來越廣泛.特別是隨著工業(yè)互聯(lián)網(wǎng)的發(fā)展,工業(yè)嵌入式軟件呈井噴式的發(fā)展.由于軟件功能的日益強(qiáng)大,軟件正在逐步取代部分硬件的功能,嵌入式軟件的規(guī)模及復(fù)雜程度急劇增加,在安全關(guān)鍵的航空航天、汽車以及工業(yè)控制等領(lǐng)域的用戶對(duì)嵌入式軟件質(zhì)量要求更加嚴(yán)格,使用過程中對(duì)嵌入式軟件缺陷的容忍度越來越低[1].
隨著工業(yè)化和信息化的深度融合,針對(duì)工業(yè)互聯(lián)網(wǎng)的安全事件頻發(fā),越來越多的攻擊者把攻擊目標(biāo)鎖定在國家關(guān)鍵工業(yè)基礎(chǔ)設(shè)施上.從2000年開始,針對(duì)工業(yè)控制系統(tǒng)的惡意攻擊事件越發(fā)頻繁,工業(yè)控制軟件一旦出現(xiàn)缺陷,將導(dǎo)致不可估量的災(zāi)難.例如:1997年9月美國艦船由于軟件非法計(jì)算導(dǎo)致推進(jìn)系統(tǒng)運(yùn)轉(zhuǎn)失敗;2004年,F(xiàn)22戰(zhàn)斗機(jī)試飛時(shí)FCS軟件缺陷導(dǎo)致墜機(jī);2006年,火星全球探勘者號(hào)的內(nèi)存地址錯(cuò)誤導(dǎo)致衛(wèi)星失聯(lián);2016年7月美國西南航空調(diào)度系統(tǒng)由于軟件緩沖區(qū)溢出導(dǎo)致系統(tǒng)崩潰,影響了7 000次航班的飛行;2019年3月,委內(nèi)瑞拉南部玻利瓦爾州的一座主要水電站發(fā)生故障,導(dǎo)致大規(guī)模停電事件,影響18個(gè)州.近年來自動(dòng)駕駛汽車的故障也造成很多交通事故[2].
工業(yè)嵌入式軟件運(yùn)行時(shí)間久、強(qiáng)度大,對(duì)安全性、可靠性以及資源的節(jié)省方面都有更多的要求,對(duì)工業(yè)嵌入式系統(tǒng)的安全性分析提出了新的挑戰(zhàn)[3].許多嵌入式軟件開發(fā)人員認(rèn)為,嵌入式系統(tǒng)的安全性應(yīng)該在系統(tǒng)級(jí)別上處理,或者由嵌入式硬件來處理,這種防御是不夠的,嵌入式系統(tǒng)的開發(fā)者需要通過處理嵌入式軟件中的漏洞來建立第3道防線.
嵌入式系統(tǒng)通常由硬件層、驅(qū)動(dòng)層和軟件層組成[4].嵌入式軟件大體上可分為3類:嵌入式操作系統(tǒng)、嵌入式支撐軟件和嵌入式應(yīng)用軟件.嵌入式操作系統(tǒng)主要用于控制、管理系統(tǒng)資源的軟件,如Windows CE,Palm OS,Linux,VxWorks,pSoS,QNX,OS-9,LynxOS等;支撐軟件是指用于輔助軟件開發(fā)的軟件工具集、交叉開發(fā)工具、軟件測(cè)試工具等;應(yīng)用軟件是嵌入式軟件中面向用戶體驗(yàn)的軟件,一般針對(duì)特定應(yīng)用領(lǐng)域、完成一定功能,達(dá)到用戶的預(yù)期目的.嵌入式應(yīng)用軟件種類最多,它不僅要求準(zhǔn)確性、安全性、穩(wěn)定性等方面能夠滿足實(shí)際應(yīng)用的要求,而且還要盡可能地進(jìn)行優(yōu)化,以減少對(duì)系統(tǒng)資源的消耗,降低硬件成本[2].
嵌入式軟件的專用性很強(qiáng),為滿足特定的領(lǐng)域需求,要求功能精簡,這樣有利于控制成本,并且可以更好地保證安全.多數(shù)嵌入式軟件固化在芯片或單片機(jī)上,提供的內(nèi)核資源相對(duì)有限,所以要求嵌入式軟件保持效率高、冗余小、功率均衡,不完善的嵌入式軟件很容易出現(xiàn)內(nèi)存問題,導(dǎo)致運(yùn)行時(shí)出現(xiàn)非預(yù)期的狀況.
嵌入式軟件具有高實(shí)時(shí)性的特點(diǎn).一方面對(duì)嵌入式軟件的質(zhì)量、可靠性和安全性有很高的要求,因?yàn)橐坏┸浖袒缶秃茈y發(fā)現(xiàn)、調(diào)試和修改軟件中的缺陷,比如由于緩沖區(qū)溢出等代碼缺陷帶來的安全隱患將更加難以修復(fù)[5];另一方面也對(duì)嵌入式軟件運(yùn)行時(shí)的實(shí)時(shí)性有比較嚴(yán)格的要求,對(duì)軟件使用的場(chǎng)景、時(shí)間、體積、功耗有嚴(yán)格要求.如果嵌入式軟件實(shí)時(shí)性差,會(huì)導(dǎo)致嚴(yán)重后果,如核電站控制、航天器入軌、飛行控制、航空發(fā)動(dòng)機(jī)控制等,均要求時(shí)間比較精準(zhǔn)[1].
工業(yè)互聯(lián)網(wǎng)軟件除了面向產(chǎn)品生產(chǎn)的研發(fā)軟件、管理軟件等,很大一部分是自動(dòng)化控制軟件或者面向裝置級(jí)的嵌入式軟件[6],即工業(yè)嵌入式軟件.工業(yè)控制的設(shè)備、協(xié)議、嵌入式軟件和系統(tǒng)在互聯(lián)網(wǎng)上暴露問題是工業(yè)互聯(lián)網(wǎng)安全的一個(gè)基本問題,直接面臨互聯(lián)網(wǎng)上的各類攻擊.對(duì)于工業(yè)嵌入式軟件而言,最大的風(fēng)險(xiǎn)來自安全漏洞,包括開發(fā)過程中編碼不符合安全規(guī)范而導(dǎo)致的軟件本身的漏洞,以及由于大量使用不安全的第三方組件而出現(xiàn)的安全漏洞[7],第三方組件的安全性和可控性問題日漸突出,一旦出現(xiàn)漏洞就會(huì)影響大量的工業(yè)產(chǎn)品[8],直接關(guān)系工業(yè)生產(chǎn)的成敗.
C語言是嵌入式軟件開發(fā)最常用的一種語言[9],C語言運(yùn)行效率非常高并且可以方便訪問硬件.然而,C語言在不同的編譯器編譯時(shí)會(huì)出現(xiàn)不同的結(jié)果,從而導(dǎo)致不可預(yù)期的問題,這是一個(gè)極大的隱患.隨著工業(yè)嵌入式軟件程序的日益復(fù)雜,軟件的代碼行數(shù)越來越多,如:NASA航天飛機(jī)的機(jī)載系統(tǒng)有近50萬行代碼,地面控制和處理也有35萬行代碼;一般的車輛控制系統(tǒng)有數(shù)百萬行代碼甚至上億行代碼.除了C語言,C++語言也越來越多地用于嵌入式軟件開發(fā)中,如美國的F-35戰(zhàn)斗機(jī)的控制系統(tǒng)就是采用C++語言編碼,其機(jī)載和地面的嵌入式系統(tǒng)代碼高達(dá)1 500萬行.隨著工業(yè)嵌入式軟件代碼規(guī)模越來越大,越來越多的嵌入式關(guān)鍵系統(tǒng)已經(jīng)成為軟件密集型系統(tǒng)[3].保證工業(yè)嵌入式軟件代碼安全成為越來越嚴(yán)峻的問題.
為了保證嵌入式軟件代碼的安全性、可靠性和可維護(hù)性,嵌入式軟件的編碼標(biāo)準(zhǔn)也越來越重要[2].國際上已經(jīng)制定了面向多個(gè)工業(yè)行業(yè)的安全標(biāo)準(zhǔn),在《IEC 6150電氣/電子/可編程電子安全系統(tǒng)的功能安全標(biāo)準(zhǔn)》《ISO 26262道路車輛功能安全標(biāo)準(zhǔn)》《CENELEC EN 50128鐵路應(yīng)用-通信,信號(hào)和處理系統(tǒng)-軟件鐵路控制和保護(hù)系統(tǒng)標(biāo)準(zhǔn)》《RTCA DO-178B/C機(jī)載軟件適航標(biāo)準(zhǔn)》中都提出要通過嵌入式開發(fā)語言的編碼標(biāo)準(zhǔn),來驗(yàn)證嵌入式軟件安全性的原則.在嵌入式軟件開發(fā)過程中,軟件開發(fā)人員嚴(yán)格按照安全編碼標(biāo)準(zhǔn)進(jìn)行編碼實(shí)施,可以在編碼階段預(yù)防安全缺陷的產(chǎn)生[10],并且可以提升安全缺陷的修復(fù)效率,在軟件開發(fā)過程的源頭減少安全缺陷,這是避免嵌入式系統(tǒng)在實(shí)際應(yīng)用環(huán)境下被攻擊的有效方法之一.隨著工業(yè)軟件的發(fā)展,嵌入式軟件安全編碼標(biāo)準(zhǔn)也在不斷的發(fā)展,其發(fā)展過程如圖1所示:
目前在工業(yè)嵌入式軟件開發(fā)中使用比較廣泛的安全編碼標(biāo)準(zhǔn)是MISRA C和MISRA C++[10],其主要來源于福特和羅孚汽車公司的C開發(fā)標(biāo)準(zhǔn),以及美國的聯(lián)合攻擊機(jī)、英國國防部的C++編碼標(biāo)準(zhǔn).MISRA 中的規(guī)則條目通過不斷的更新和更正,成為了最新的MISRA C:2012以及MISRA C++:2008.為了補(bǔ)充嵌入式軟件安全編碼標(biāo)準(zhǔn)中風(fēng)格類的編碼規(guī)則,美國BARR組織推出了BARR C標(biāo)準(zhǔn)用于補(bǔ)充MISRA C:2012標(biāo)準(zhǔn)[12].2020年在德國召開的Embedded World會(huì)議上,BARR C:2018和MISRA C:2012協(xié)同作用的主題中提到BARR嵌入式C編碼標(biāo)準(zhǔn)可以幫助嵌入式軟件開發(fā)人員在進(jìn)行調(diào)試時(shí),去除嵌入式軟件的代碼錯(cuò)誤,提升其可維護(hù)性和可移植性,幫助企業(yè)和個(gè)人開發(fā)出高可靠性的嵌入式軟件[12],從而進(jìn)一步提升軟件的安全性.近年來,隨著汽車工業(yè)的發(fā)展,汽車嵌入式軟件需求越來越多,汽車電子標(biāo)準(zhǔn)組織AUTOSAR開發(fā)聯(lián)盟提出了AUTOSAR C++編碼標(biāo)準(zhǔn),這套標(biāo)準(zhǔn)的規(guī)則主要來源于MISRA C++:2018以及HICPP規(guī)范.MISRA C/C++工作組成員Rozenau在2019年曾提出MISRA C++標(biāo)準(zhǔn)和AUTOSAR C++標(biāo)準(zhǔn)的檢測(cè)規(guī)則密不可分,并計(jì)劃將AUTOSAR C++與MISRA C++相互補(bǔ)充[13].AUTOSAR C++的出現(xiàn)極大推動(dòng)了工業(yè)嵌入式軟件安全編碼標(biāo)準(zhǔn)的發(fā)展.
AUTOSAR C++還借鑒了CERT C和CERT C++安全編碼標(biāo)準(zhǔn),CERT是由軟件工程研究所(SEI)為嵌入式開發(fā)人員創(chuàng)建的.專家從CERT C中提取出一套適用于靜態(tài)分析技術(shù)的規(guī)則集,成為ISO/IEC TS 17961《C安全編碼規(guī)則》.標(biāo)準(zhǔn)中提出45條適用于工業(yè)嵌入式軟件的編碼標(biāo)準(zhǔn),一旦違背這些標(biāo)準(zhǔn),會(huì)導(dǎo)致系統(tǒng)崩潰等問題[14].CERT C和CERT C++安全編碼標(biāo)準(zhǔn)都收錄于CWETM(Common Weakness Enumeration)表中.CWE表是由美國國家安全局首先倡議的戰(zhàn)略行動(dòng),其中收錄了大部分已發(fā)現(xiàn)的軟硬件安全漏洞.在每年最嚴(yán)重的CWE TOP 25中至少有10個(gè)都是嵌入式軟件開發(fā)相關(guān)的安全漏洞,這些條目長年被排在CWE TOP 25中,需要相關(guān)人員在嵌入式軟件開發(fā)中高度重視并且提早解決.CWE TOP 25中的嵌入式軟件開發(fā)安全漏洞如表1所示:
表1 CWE TOP 25中的嵌入式軟件開發(fā)安全漏洞
隨著國內(nèi)嵌入式軟件的發(fā)展,國內(nèi)推出了工業(yè)嵌入式軟件標(biāo)準(zhǔn)GB/T 28169—2011《嵌入式軟件C語言編碼規(guī)范》,但是目前應(yīng)用不是很廣泛.GB/T 28169 C—2011中包含一些針對(duì)嵌入式軟件特定的規(guī)則,如中斷、寄存器缺陷、硬件系統(tǒng)初始化等.
針對(duì)MISRA C++:2008、MISRA C:2012、BARR C:2018、AUTOSAR C++、CERT C/C++、ISO/IE TS 17961 C、CWE表、GB/T 28169 C—2011這些目前比較常見的國內(nèi)外嵌入式軟件安全編碼標(biāo)準(zhǔn),從發(fā)起圖家和地區(qū)、發(fā)布時(shí)間及情況、發(fā)布組織、規(guī)則數(shù)目、適用領(lǐng)域以及規(guī)則集特點(diǎn)進(jìn)行對(duì)比,如表2所示.
表2 嵌入式軟件安全編碼標(biāo)準(zhǔn)對(duì)比
這些常用的嵌入式軟件安全編碼標(biāo)準(zhǔn)之間,在具體規(guī)則項(xiàng)上也有一定的關(guān)聯(lián)和覆蓋,如圖2所示.
圖2 嵌入式軟件安全編碼標(biāo)準(zhǔn)關(guān)聯(lián)關(guān)系[12-16]
本文基于對(duì)嵌入式軟件安全編碼標(biāo)準(zhǔn)的研究,進(jìn)一步對(duì)標(biāo)準(zhǔn)之間的關(guān)聯(lián)關(guān)系進(jìn)行詳細(xì)的分析、比較和去重,篩選和抽取出工業(yè)嵌入式軟件開發(fā)安全漏洞模式清單.漏洞模式共分為3大類,即嵌入式軟件特有安全漏洞模式、通用類嚴(yán)重缺陷模式和其他缺陷模式,每種大類下包含若干種缺陷模式小類.通過進(jìn)一步分析缺陷模式中各種情況,參考國內(nèi)外各套安全編碼標(biāo)準(zhǔn)的詳細(xì)內(nèi)容抽取出若干具體的模式檢測(cè)規(guī)則.
嵌入式特有模式主要與嵌入式軟件密切相關(guān),例如硬件初始化、并發(fā)性、原子性、中斷等嵌入式特定情況相關(guān)的一些缺陷模式,這些缺陷模式主要來自于GB/T 28169—2011《嵌入式軟件C語言編碼規(guī)范》,是與嵌入式系統(tǒng)硬件相關(guān)或者是嵌入式軟件中特有的編程用法,在嵌入式軟件中出現(xiàn)這些缺陷后,會(huì)導(dǎo)致嵌入式系統(tǒng)崩潰等問題.這類模式包括8種缺陷模式小類、26種模式檢測(cè)規(guī)則,如表3所示:
表3 嵌入式軟件特有安全漏洞模式
這些模式檢測(cè)規(guī)則是規(guī)定編碼的詳細(xì)條目描述,針對(duì)每種模式具體的檢測(cè)規(guī)則舉例,如果使用靜態(tài)代碼分析技術(shù)對(duì)被測(cè)嵌入式軟件代碼進(jìn)行檢測(cè),就要首先對(duì)規(guī)則進(jìn)行詳細(xì)說明,以及添加正確和錯(cuò)誤例子代碼,建立完整的安全漏洞模式知識(shí)庫,如表3中,序號(hào)“1”中“寄存器缺陷”的漏洞模式規(guī)則舉例“中斷處理程序和主程序寄存器組沖突”,是指在中斷函數(shù)中調(diào)用其他函數(shù),必須和中斷函數(shù)使用相同的寄存器組.這是因?yàn)橹鞒绦蚰J(rèn)使用的寄存器為BANK0,如果中斷函數(shù)沒有通過using指定寄存器組或者指定了相同的寄存器組,則不會(huì)發(fā)生沖突;如果中斷函數(shù)通過using指定了不同的寄存器組,則被調(diào)用的函數(shù)需要放在#pragma NOAREGS和#pragma AREGS控制參數(shù)對(duì)中,該參數(shù)對(duì)的意義是使編譯器不要對(duì)該函數(shù)使用絕對(duì)寄存器尋址.當(dāng)沒有用NOAREGS參數(shù)作明確的聲明,編譯器將絕對(duì)寄存器尋址方式訪問函數(shù)選定(即使用using或REGISTERBANK指定)的寄存器組,當(dāng)函數(shù)假定的和實(shí)際所選的寄存器組不同時(shí)將產(chǎn)生不可預(yù)知的結(jié)果,從而可能出現(xiàn)參數(shù)傳遞錯(cuò)誤,返回值可能會(huì)在錯(cuò)誤的寄存器組中.
除了嵌入式特有的模式,還有一些安全漏洞模式在所有C/C++語言開發(fā)的軟件中都通用,并且在嵌入式軟件中錯(cuò)誤使用會(huì)導(dǎo)致嚴(yán)重的問題,如導(dǎo)致嵌入式系統(tǒng)崩潰或者拒絕服務(wù)等嚴(yán)重后果.這類缺陷模式歸為通用類嚴(yán)重缺陷模式,這類缺陷模式在各個(gè)編碼標(biāo)準(zhǔn)中都可能出現(xiàn),可以用于C/C++語言編寫的各類應(yīng)用軟件代碼的檢測(cè)中.這類嚴(yán)重缺陷包括20種模式小類、89種模式檢測(cè)規(guī)則,如表4所示:
表4 通用類嚴(yán)重缺陷模式
通用類嚴(yán)重缺陷模式也要在安全漏洞模式庫中進(jìn)行建立,如表4序號(hào)2中的“動(dòng)態(tài)鏈接庫”的漏洞模式檢測(cè)規(guī)則“調(diào)用外部文件未使用完整路徑”,指的是在應(yīng)用程序加載外部庫時(shí),代碼應(yīng)該使用完全限定的路徑,這一點(diǎn)很重要.如果指定了不完全限定的路徑,則惡意攻擊者就可以控制搜索路徑,并且將其用作遠(yuǎn)程執(zhí)行任意代碼的載體,某些 API(例如 SearchPath)也提供可用于惡意攻擊的載體,它們會(huì)嘗試從非預(yù)期的源目錄中加載庫,這些類型的威脅稱為二進(jìn)制植入或DLL預(yù)加載攻擊.比如直接使用相對(duì)路徑調(diào)用外部文件,寫成LoadLibrary(“external_library.dll”).這會(huì)導(dǎo)致相對(duì)路徑可能被惡意攻擊者利用以執(zhí)行任意代碼.應(yīng)該改為在調(diào)用外部文件時(shí)使用完整路徑,寫成 LoadLibrary(“C:/libs/external_library.dll”).
表4中序號(hào)17中的“密碼權(quán)限”的漏洞模式檢測(cè)規(guī)則“明文存儲(chǔ)密碼”也是很常見的一種嚴(yán)重安全漏洞模式.2018年10月9日,美國政府問責(zé)局發(fā)布了題為“WEAPON SYSTEMS CYBERSECURITY-Just Beginning to Grapple with Scale of Vulnerabilities”的報(bào)告中提到美國國防部大部分正在開發(fā)的武器嵌入式系統(tǒng)中都存在安全漏洞,最多的安全漏洞就是密碼被非法獲取.當(dāng)密碼以純文本格式存儲(chǔ)在應(yīng)用程序的屬性或配置文件中時(shí),任何可以讀取該文件的人都可以訪問受密碼保護(hù)的資源,極大地危及整個(gè)嵌入式系統(tǒng)的安全.應(yīng)該避免將密碼存儲(chǔ)在易于訪問的位置,也不要使用純文本格式存儲(chǔ)任何敏感信息,并使用合適的加密方法對(duì)密碼進(jìn)行加密.
能展示日常工作情況。競(jìng)賽是崗位練兵活動(dòng)中又一大內(nèi)容,通過競(jìng)賽的形式,模擬住宅火災(zāi)救援、林地火情控制等等,在競(jìng)賽時(shí)“濫竽充數(shù)”、“混水摸魚”是行不通的,日常的工作情況將真實(shí)的反映在考官的面前,或優(yōu)或劣的工作情況得到了有效展示,通過競(jìng)賽形式,促使了員工立足崗位,苦練過硬本領(lǐng)、學(xué)技術(shù),練絕活,干一流,爭第一,爭當(dāng)崗位能手的自覺性。
其他缺陷模式檢測(cè)規(guī)則有300多種,主要針對(duì)函數(shù)、變量、循環(huán)、跳轉(zhuǎn)等編碼風(fēng)格、樣式規(guī)范性的一些要求,這一類缺陷模式也來源于各個(gè)編碼標(biāo)準(zhǔn).如果在嵌入式軟件的編碼過程中出現(xiàn)其他類的缺陷模式,一般不會(huì)導(dǎo)致嚴(yán)重的后果,但是會(huì)讓代碼存在潛在隱患,并且導(dǎo)致嵌入式軟件的代碼不容易維護(hù).如函數(shù)類的“有返回值的函數(shù)中return必須帶有返回值”這條規(guī)則在MISRA2012和CWE的編碼標(biāo)準(zhǔn)中都有提到.這條規(guī)則是指函數(shù)類型不是void,但是函數(shù)內(nèi)的return并沒有返回值,那么返回值就未被賦值,這可能導(dǎo)致使用未初始化的內(nèi)存.當(dāng)返回值在其他地方被用到時(shí),會(huì)導(dǎo)致未知的錯(cuò)誤.
工業(yè)嵌入式軟件安全漏洞可以通過靜態(tài)分析和動(dòng)態(tài)分析2類技術(shù)進(jìn)行檢測(cè).其中:動(dòng)態(tài)分析結(jié)合程序運(yùn)行行為進(jìn)行檢測(cè),一般不需要指定漏洞模式,只要程序運(yùn)行時(shí)滿足某個(gè)條件(如程序崩潰)就可以發(fā)現(xiàn)安全漏洞;代碼靜態(tài)分析技術(shù)在不運(yùn)行程序的情況下對(duì)代碼進(jìn)行分析,通常以安全漏洞模式為輸入,可用于檢測(cè)嵌入式軟件中特定模式的安全漏洞.下面對(duì)靜態(tài)分析技術(shù)進(jìn)行介紹.
代碼靜態(tài)分析技術(shù)越來越被認(rèn)為是高級(jí)編程語言的高性能實(shí)現(xiàn)和驗(yàn)證系統(tǒng)的基本工具[17].代碼靜態(tài)分析技術(shù)主要分為基于語法和基于路徑遍歷2類靜態(tài)分析技術(shù),其中基于路徑遍歷的分析技術(shù)以語法分析為基礎(chǔ),進(jìn)一步分析程序中變量之間的控制流和數(shù)據(jù)流關(guān)系.接下來以2類嵌入式軟件漏洞模式為例,介紹對(duì)應(yīng)的分析方法.
對(duì)于中斷規(guī)范這種規(guī)則類的漏洞模式,基于語法即可準(zhǔn)確分析.根據(jù)用戶指定的中斷服務(wù)程序,對(duì)代碼進(jìn)行詞法、語法分析,生成抽象語法樹,樹中的各個(gè)結(jié)點(diǎn)表示函數(shù)、語句、表達(dá)式、變量等不同類型的程序元素,邊表示各個(gè)程序元素之間的包含關(guān)系.然后,對(duì)抽象語法樹進(jìn)行遍歷.對(duì)于函數(shù)定義類型和語句類型的樹結(jié)點(diǎn),檢查定義中的返回類型聲明是否存在,或者語句是否為返回語句,若是即違反“中斷服務(wù)程序不應(yīng)帶有返回值”的規(guī)范;對(duì)于函數(shù)調(diào)用類型的樹結(jié)點(diǎn),若存在被調(diào)用函數(shù)名為printf,malloc的函數(shù),即違反“不應(yīng)在中斷服務(wù)程序中使用printf,malloc等函數(shù)”的規(guī)范.
對(duì)于其他大多數(shù)的漏洞模式,僅基于語法不能準(zhǔn)確分析.例如,對(duì)于“可疑的空指針解引用”這種漏洞,必須同時(shí)具備以下4個(gè)要素:1)在程序中的某個(gè)語句Si定義了空指針;2)在程序另一個(gè)語句Sj存在該指針的解引用;3)存在Si到Sj的路徑且實(shí)際可達(dá);4)在所有可達(dá)路徑中,不存在1條賦值語句,使該指針一定被賦值為非空值.可以看出,僅靠抽象語法樹上的信息不足以準(zhǔn)確分析出以上信息,需要基于抽象語法樹進(jìn)行關(guān)于程序路徑的進(jìn)一步分析,稱為基于路徑遍歷的分析技術(shù),主要包括值流分析[18]和符號(hào)執(zhí)行[19]2類.
對(duì)于值流分析,分為以下3個(gè)步驟:
步驟1.構(gòu)建控制流圖、函數(shù)調(diào)用圖、指針分析圖等若干種基礎(chǔ)程序模型,描述函數(shù)內(nèi)語句執(zhí)行順序、函數(shù)間調(diào)用、程序指針指向等關(guān)系.
步驟2.基于以上程序模型,構(gòu)建值流圖或值依賴圖等綜合圖模型,表達(dá)變量之間的控制流及數(shù)據(jù)流依賴關(guān)系.其中,控制流表達(dá)程序語句之間執(zhí)行順序的依賴關(guān)系,數(shù)據(jù)流表達(dá)變量之間在定義-使用上的依賴關(guān)系.圖中的每個(gè)結(jié)點(diǎn)表示語句中的變量,邊表示變量之間的數(shù)據(jù)流關(guān)系,邊上標(biāo)記數(shù)據(jù)流存在的條件,為約束表達(dá)式,描述了控制流關(guān)系.
步驟3.基于所分析的"可疑的空指針解引用"模式的4個(gè)要素,在綜合圖模型中進(jìn)行定位和搜索,圖模型中的結(jié)點(diǎn)可對(duì)應(yīng)到程序語句,有向邊對(duì)應(yīng)到程序中的控制流和數(shù)據(jù)流傳遞關(guān)系.首先,對(duì)于每個(gè)指針P,在圖模型中檢查是否存在使其可能為空的賦值,并將對(duì)應(yīng)結(jié)點(diǎn)記為N1;然后,進(jìn)一步在綜合圖模型中計(jì)算從N1出發(fā)的所有路徑,所得路徑即為程序切片;繼而,檢查所得程序切片中的結(jié)點(diǎn),是否存在對(duì)指針P的解引用,若存在則將該結(jié)點(diǎn)記為N2,并計(jì)算結(jié)點(diǎn)N1到達(dá)結(jié)點(diǎn)N2所需要滿足的約束表達(dá)式,因N1到N2之間可能存在多條路徑,這里對(duì)約束條件采用同一路徑取交、不同路徑取并的計(jì)算方法;最后,使用SMT約束求解技術(shù),對(duì)前序步驟中所得的約束表達(dá)式進(jìn)行求解,若結(jié)果為真,則判定存在對(duì)應(yīng)漏洞,報(bào)告相應(yīng)的路徑和可疑的空指針定義點(diǎn)及使用點(diǎn).
對(duì)于其他嵌入式安全漏洞模式,分析技術(shù)相似.其中步驟1和步驟2的計(jì)算結(jié)果為共性的模型,在不同的模式之間可以復(fù)用;步驟3特定于每種漏洞模式,但通常都涉及到圖中關(guān)鍵結(jié)點(diǎn)識(shí)別、路徑計(jì)算、約束求解這3個(gè)子步驟.
符號(hào)執(zhí)行技術(shù)同樣可以檢測(cè)這些模式,類似于值流分析,需要構(gòu)建控制流圖.與值流分析側(cè)重于通過數(shù)據(jù)流分析漏洞不同,符號(hào)執(zhí)行更側(cè)重從控制流的角度分析漏洞.其將變量用符號(hào)表示,按照程序的執(zhí)行過程,對(duì)程序進(jìn)行模擬執(zhí)行,記錄每條語句執(zhí)行后程序中各個(gè)變量符號(hào)和約束表達(dá)式等程序狀態(tài)的變化.對(duì)于“可疑的空指針解引用”模式,當(dāng)依次監(jiān)測(cè)到可疑空指針賦值和對(duì)該指針進(jìn)行解引用的語句執(zhí)行后,對(duì)所記錄的約束表達(dá)式進(jìn)行求解,即可發(fā)現(xiàn)是否存在一條可達(dá)的路徑,進(jìn)而判斷是否存在該漏洞.
可以看出,值流分析和符號(hào)執(zhí)行都使用了約束求解的技術(shù),該技術(shù)在大規(guī)模程序中會(huì)有約束表達(dá)式過于復(fù)雜導(dǎo)致無法求解的問題.此外,嵌入式程序本身的靜態(tài)分析模型構(gòu)建過程也因?yàn)槌绦虻膹?fù)雜性,在跨函數(shù)、域敏感、上下文敏感等場(chǎng)景上,必須犧牲部分精度,以達(dá)到可接受的分析效率.因此,靜態(tài)分析的結(jié)果不能保證正確,其對(duì)漏洞檢測(cè)的誤報(bào)率、漏報(bào)率和檢測(cè)效率也是衡量不同檢測(cè)技術(shù)的關(guān)鍵指標(biāo).不同的技術(shù)路線都有其優(yōu)化方法[20-23],并可持續(xù)改進(jìn),以期在滿足一定檢測(cè)效率的基礎(chǔ)上,盡可能降低誤報(bào)和漏報(bào).
本文介紹了工業(yè)嵌入式軟件的安全特點(diǎn),并對(duì)工業(yè)嵌入式軟件相關(guān)的最常用的C,C++的國內(nèi)外安全編碼標(biāo)準(zhǔn)MISRA C,CERT C,GB/T 28169等進(jìn)行說明,從各個(gè)標(biāo)準(zhǔn)的發(fā)展過程、標(biāo)準(zhǔn)特點(diǎn)以及各標(biāo)準(zhǔn)之間關(guān)聯(lián)覆蓋關(guān)系進(jìn)行分析,進(jìn)而提出一套適用于工業(yè)嵌入式軟件的安全漏洞模式清單,模式分為3大類,包括:嵌入式特有的安全漏洞模式、通用類嚴(yán)重缺陷模式以及規(guī)范性的其他缺陷模式.最后介紹了基于語法和基于路徑遍歷2類靜態(tài)分析技術(shù)對(duì)這些安全漏洞模式的代碼檢測(cè)實(shí)現(xiàn),并針對(duì)一些工業(yè)嵌入式軟件開發(fā)安全漏洞模式的分析檢測(cè)實(shí)現(xiàn)進(jìn)行詳細(xì)說明.通過使用靜態(tài)分析技術(shù),對(duì)工業(yè)嵌入式軟件進(jìn)行安全漏洞模式分析和檢測(cè),在軟件開發(fā)過程的源頭發(fā)現(xiàn)編碼安全問題并得到及時(shí)解決,可以更好保證工業(yè)軟件的安全,進(jìn)一步推動(dòng)工業(yè)軟件的發(fā)展和工業(yè)互聯(lián)網(wǎng)的發(fā)展.