姜 文,劉立康
(西安電子科技大學(xué) 通信工程學(xué)院,陜西 西安 710071)
C++與Java軟件重量級(jí)靜態(tài)檢查
姜 文,劉立康
(西安電子科技大學(xué) 通信工程學(xué)院,陜西 西安 710071)
為了保證Windows環(huán)境下C/C++和Java軟件產(chǎn)品質(zhì)量,對(duì)C/C++代碼和Java代碼進(jìn)行靜態(tài)檢查非常重要。以SVN作為軟件配置管理工具,將重量級(jí)靜態(tài)檢查工具Coverity和Fortify集成到持續(xù)集成工具ICP-CI上,分別對(duì)C/C++代碼和Java代碼進(jìn)行重量級(jí)靜態(tài)檢查。詳細(xì)敘述了Windows環(huán)境下軟件配置管理工具SVN客戶端安裝,SVN版本庫(kù)的代碼更新,對(duì)C/C++和Java代碼分別進(jìn)行Coverity和Fortify編譯器的配置、編譯腳本編寫(xiě)和在ICP-CI任務(wù)管理頁(yè)面上配置檢查任務(wù)。介紹了靜態(tài)檢查處理過(guò)程,分析了出現(xiàn)各種常見(jiàn)問(wèn)題的原因并提出了相應(yīng)的解決方案。給出了一個(gè)軟件產(chǎn)品中C/C++代碼模塊和Java代碼模塊的重量級(jí)靜態(tài)檢查應(yīng)用案例。工作實(shí)踐表明,進(jìn)行重量級(jí)靜態(tài)檢查有助于及時(shí)發(fā)現(xiàn)并解決C/C++和Java軟件源代碼的各種缺陷和安全漏洞,從而提高軟件產(chǎn)品的質(zhì)量和安全性。
Windows操作系統(tǒng);靜態(tài)檢查;持續(xù)集成;安全漏洞
Windows操作系統(tǒng)是具有圖形界面的操作系統(tǒng),是完全的多任務(wù)操作系統(tǒng),是使用最多且排名第一的操作系統(tǒng)。Windows操作系統(tǒng)提供功能強(qiáng)大的應(yīng)用程序編程接口。目前在Windows環(huán)境下流行的軟件開(kāi)發(fā)語(yǔ)言主要有C++、C#和Java。
在Windows環(huán)境下通常采用集成開(kāi)發(fā)環(huán)境Visual Studio進(jìn)行VC/C++、C#程序設(shè)計(jì)。VC編譯器[1-2]通常位于bin目錄中。cl.exe是VC/C++編譯器。編譯器產(chǎn)生通用對(duì)象文件格式(COFF)對(duì)象(.obj)文件。LINK.EXE是將通用對(duì)象文件格式(COFF)對(duì)象文件和庫(kù)鏈接起來(lái)以創(chuàng)建32位可執(zhí)行(.exe)文件或動(dòng)態(tài)鏈接庫(kù)(DLL)的32位工具。C#編譯器是csc.exe。
在Windows環(huán)境下通常采用Eclipse進(jìn)行Java程序設(shè)計(jì)。Java編程需要下載安裝Java的軟件開(kāi)發(fā)工具JDK[3-4],JDK目錄的bin文件夾中包含Java編譯器javac.exe和Java解釋器java.exe。Java源程序都是擴(kuò)展名為.java的文本文件,編譯后生成可執(zhí)行代碼,文件名與源文件名相同,擴(kuò)展名為.class。運(yùn)行java.exe來(lái)執(zhí)行該Java程序。
在Windows環(huán)境下的軟件開(kāi)發(fā)大部分都是基于C/C++語(yǔ)言和Java語(yǔ)言。為了保證基于軟件產(chǎn)品代碼質(zhì)量,檢測(cè)軟件源代碼中存在的缺陷和安全漏洞[5-7]非常重要。文中采用CodeCC(Code Check Center)工具壓縮包進(jìn)行檢測(cè)。工具壓縮包中包括靜態(tài)檢查工具Coverity[8-11]和Fortify[12-15],采用靜態(tài)檢查方法檢測(cè)源代碼的缺陷和安全漏洞,將檢查結(jié)果反饋給開(kāi)發(fā)人員及時(shí)處理,從而提高軟件的質(zhì)量和安全性。
靜態(tài)測(cè)試工具直接對(duì)代碼進(jìn)行分析,不需要運(yùn)行代碼,也不需要生成可執(zhí)行文件。靜態(tài)測(cè)試工具一般是對(duì)代碼進(jìn)行語(yǔ)法掃描,找出不符合編碼規(guī)范的地方,根據(jù)某種質(zhì)量模型評(píng)價(jià)代碼的質(zhì)量,生成系統(tǒng)的調(diào)用關(guān)系圖等。通常把Coverity和Fortify稱為重量級(jí)的靜態(tài)檢查工具。
1.1 Coverity Prevent
Coverity Prevent是由美國(guó)Coverity公司開(kāi)發(fā)的一款高性能靜態(tài)檢查軟件。Coverity公司提供最先進(jìn)的、可配置的、用于檢測(cè)軟件缺陷和安全隱患的靜態(tài)源代碼分析解決方案。將基于布爾可滿足性驗(yàn)證技術(shù)應(yīng)用于源代碼分析引擎,分析引擎利用其專利的軟件DNA圖譜技術(shù)和meta-compilation技術(shù),綜合分析源代碼、編譯構(gòu)建系統(tǒng)和操作系統(tǒng)等可能使軟件產(chǎn)生的缺陷。通過(guò)對(duì)構(gòu)建環(huán)境、源代碼和開(kāi)發(fā)過(guò)程給出一個(gè)完整的分析,建立了高質(zhì)量軟件的標(biāo)準(zhǔn)。Coverity Prevent是第一個(gè)能夠快速、準(zhǔn)確分析當(dāng)今大規(guī)模(幾百萬(wàn)甚至幾千萬(wàn)行的代碼)、高復(fù)雜度代碼的工具。Coverity解決了影響源代碼分析有效性的很多關(guān)鍵問(wèn)題:構(gòu)建集成、編譯兼容性、高誤報(bào)率、有效的錯(cuò)誤根源分析等。
Coverity Prevent的主要功能包括源代碼分析、缺陷管理、擴(kuò)展工具(Coverity extend)、繪制軟件DNA圖譜。Coverity Prevent是檢測(cè)和解決C、C++、Java和C#源代碼中嚴(yán)重缺陷的領(lǐng)先自動(dòng)化方法。在Windows環(huán)境下,Coverity Prevent支持集成開(kāi)發(fā)環(huán)境Visual Studio,支持VC/C++編譯器和C#編譯器CSC.exe;支持集成開(kāi)發(fā)環(huán)境Eclipse,支持Java編譯器javac.exe。
1.2 Fortify SCA
HP Fortify是目前全球最大的靜態(tài)源代碼檢測(cè)廠商。靜態(tài)代碼分析器Fortify SCA(Static Code Analyzer)是該公司開(kāi)發(fā)的一款軟件源代碼缺陷靜態(tài)測(cè)試工具。采用數(shù)據(jù)流分析引擎、語(yǔ)義分析引擎、結(jié)構(gòu)分析引擎、控制流分析引擎、配置分析引擎和特有的X-Tier跟蹤器,從不同的方面查看代碼的缺陷和安全漏洞。
Fortify SCA通過(guò)調(diào)用語(yǔ)言的編譯器或者解釋器把源代碼轉(zhuǎn)換成一種中間媒體文件*.nst(Normal Syntax Tree),對(duì)應(yīng)用軟件的源代碼進(jìn)行靜態(tài)分析。在分析過(guò)程中與它特有的軟件安全漏洞規(guī)則集進(jìn)行全面的匹配、查找,從而將源代碼中存在的缺陷和安全漏洞掃描出來(lái),并整理報(bào)告。掃描結(jié)果中不但包括詳細(xì)的安全漏洞的信息,還會(huì)有相關(guān)的安全知識(shí)的說(shuō)明,同時(shí)提供修復(fù)意見(jiàn)。
Fortify SCA支持的編程語(yǔ)言多達(dá)17種,包括C、C++、C#、Java等,基本涵蓋了絕大多數(shù)的應(yīng)用,具有相當(dāng)廣泛的適用性。Fortify SCA廣泛的適用性使其適用于橫跨多種語(yǔ)言的開(kāi)發(fā)和測(cè)試。在Windows環(huán)境下,F(xiàn)ortify SCA支持集成開(kāi)發(fā)環(huán)境Visual Studio,支持VC/C++編譯器和C#編譯器CSC.exe;支持集成開(kāi)發(fā)環(huán)境Eclipse,支持Java編譯器javac.exe。
通常軟件產(chǎn)品在開(kāi)發(fā)階段每天都要把源代碼合入版本庫(kù)中。為了保證軟件源代碼的質(zhì)量,每周至少對(duì)合入版本庫(kù)的源代碼進(jìn)行2~3次Coverity和Fortify檢查。手動(dòng)執(zhí)行腳本調(diào)用Coverity和Fortify工具生成編譯中間文件后,再上傳到分析中心耗時(shí)長(zhǎng)、效率低,不能及時(shí)提供檢查結(jié)果。
2.1 基本的構(gòu)建系統(tǒng)模型
現(xiàn)在通常采用持續(xù)集成工具來(lái)完成靜態(tài)檢查任務(wù)。持續(xù)集成[16]工具可以提供方便的集成平臺(tái),可以設(shè)置定時(shí)任務(wù),使Coverity和Fortify檢查任務(wù)能夠充分利用非工作時(shí)間完成編譯和靜態(tài)分析等比較耗時(shí)的執(zhí)行過(guò)程,保證及時(shí)得到分析結(jié)果,方便開(kāi)發(fā)人員根據(jù)檢查結(jié)果報(bào)告修改產(chǎn)品源代碼缺陷。圖1顯示了一個(gè)基本的構(gòu)建系統(tǒng)視圖。
圖1 構(gòu)建系統(tǒng)視圖
構(gòu)建流程如下:
(1)軟件開(kāi)發(fā)工程師編寫(xiě)或修改代碼。
(2)開(kāi)發(fā)工程師向軟件配置管理(SCM)系統(tǒng)的版本庫(kù)提交驗(yàn)證通過(guò)的源代碼。
(3)持續(xù)集成工程師(CIE)編寫(xiě)腳本和靜態(tài)檢查編譯器配置。
(4)持續(xù)集成工程師在持續(xù)集成工具的任務(wù)管理頁(yè)面上配置構(gòu)建任務(wù)和靜態(tài)檢查任務(wù)。
(5)持續(xù)集成工程師制定構(gòu)建定時(shí)任務(wù)(通常是非工作時(shí)間)自動(dòng)進(jìn)行集成構(gòu)建。
(6)編譯中生成的中間文件上傳到靜態(tài)檢查分析中心并運(yùn)行靜態(tài)分析工具。
(7)靜態(tài)檢查結(jié)果發(fā)送到持續(xù)集成工具。
(8)持續(xù)集成工具通過(guò)電子郵件向軟件產(chǎn)品經(jīng)理和開(kāi)發(fā)工程師及時(shí)反饋構(gòu)建結(jié)果和靜態(tài)檢查結(jié)果。
(9)軟件開(kāi)發(fā)工程師下載檢查報(bào)告及時(shí)處理存在的各種問(wèn)題。
文中采用的軟件配置管理工具是SVN,持續(xù)集成工具是ICP-CI。由于使用的編譯環(huán)境是Windows,首先將集成了Coverity和Fortify工具的CodeCC工具的壓縮包CodeCC_Win32.zip拷貝到持續(xù)集成主控服務(wù)器與代理服務(wù)器的plugin目錄下解壓,再分別對(duì)Coverity和Fortify工具進(jìn)行相關(guān)的編譯器配置,然后完成搭建構(gòu)建工程。構(gòu)建工程命名為:“產(chǎn)品名_版本號(hào)_CodeCheck”。
2.2 軟件配置管理工具SVN
2.2.1 Windows環(huán)境下的SVN客戶端安裝
ICP-CI服務(wù)器通常需要安裝SVN命令行工具和圖形SVN客戶端工具TortoiseSVN。安裝完成命令行工具和圖形客戶端工具之后,可以選擇安裝支持中文操作的軟件語(yǔ)言包。
完成SVN工具的安裝之后,可以根據(jù)配置管理工程師提供的產(chǎn)品代碼配置庫(kù)路徑,使用SVN客戶端工具的“SVN檢出(check out)”功能從配置庫(kù)下載代碼到代理服務(wù)器的指定路徑下。
2.2.2 SVN版本庫(kù)的代碼更新
持續(xù)集成工具ICP-CI需要在版本庫(kù)鎖庫(kù)之后完成源代碼更新,ICP-CI工具執(zhí)行代碼更新時(shí),需要編寫(xiě)批處理腳本Code_Update.bat,把腳本配置在任務(wù)中。更新代碼的批處理腳本內(nèi)容如下:
::配置需要更新代碼的視圖路徑
SET CodePath=D:/Code
::解除代碼視圖中的文件鎖定
svn cleanup % CodePath %
::更新代碼到視圖路徑
svn update % CodePath % --accept postpone
Windows環(huán)境下的C/C++程序設(shè)計(jì)通常采用Microsoft Visual Studio2010集成工具,但是也有一些老的軟件產(chǎn)品C/C++編程采用VC6.0集成工具。對(duì)C/C++代碼的靜態(tài)檢查需要處理兩種情況。
(1)Coverity編譯器配置。
軟件產(chǎn)品模塊進(jìn)行Coverity檢查時(shí),需要在模塊源代碼進(jìn)行編譯的時(shí)候調(diào)用Coverity工具中的cov_configure命令。為了在編譯過(guò)程中成功調(diào)用cov_configure命令,需要完成編譯器的配置。
對(duì)于Windows環(huán)境下的C/C++程序,編譯器配置在tqeconfig.ini文件中。
編程使用的VC6.0編譯器配置內(nèi)容如下:
msvc=D:ToolsMicrosoft Visual StudioVC98incl.exe
編程使用的Microsoft Visual Studio2010編譯器配置內(nèi)容如下:
msvc=D:ToolsMicrosoft Visual Studio10.0VCincl.exe
在配置過(guò)程中需要注意的是,cl.exe為工具的安裝路徑,實(shí)際在配置過(guò)程中可以根據(jù)Microsoft Visual Studio工具的實(shí)際安裝路徑進(jìn)行配置。
完成編譯器配置后,執(zhí)行tqeconfig.bat文件,該文件如果執(zhí)行成功,則將生成相應(yīng)的配置文件保存在CodeCC oolcoverityconfig目錄下。在配置編譯器時(shí)需要注意tqeconfig.bat腳本的執(zhí)行結(jié)果,當(dāng)執(zhí)行窗口中提示執(zhí)行成功,配置的編譯器才能在CodeCC oolcoverityconfig目錄下生成對(duì)應(yīng)編譯器的配置文件。
完成編譯器配置后,需要將持續(xù)集成主控服務(wù)器和代理服務(wù)器上的coverity工具路徑:pluginCodeCC oolcoverityin路徑添加到環(huán)境變量path中。
(2)Coverity編譯腳本編寫(xiě)。
Coverity任務(wù)配置到ICP-CI上之后,通常由主控服務(wù)器將任務(wù)下發(fā)到代理服務(wù)器執(zhí)行。執(zhí)行Coverity任務(wù)需要編寫(xiě)相應(yīng)的編譯腳本,使Coverity任務(wù)執(zhí)行時(shí)能夠調(diào)用cov-configure來(lái)編譯Microsoft Visual Studio的工程文件。
編程使用VC6.0,編譯腳本內(nèi)容如下:
cd/d “D:CodeSecurity_Versionsalm_srcMake PC”
“D:ToolsMicrosoft Visual StudioCommonMSDev98BinMSDEV.exe” “Make PC.dsw” /make “Make PC -win32 RELAESE” /clean
“D:ToolsMicrosoft Visual StudioCommonMSDev98BinMSDEV.exe” “Make PC.dsw” /make “Make PC -win32 RELAESE” /rebuild
編程使用Microsoft Visual Studio2010,編譯腳本內(nèi)容如下:
cd/d “D:CodeSecurity_VersionsCZLog”
“D:ToolsMicrosoft Visual Studio 10.0Common7IDEdevenv” “CZLog.sln” / clean
“D:ToolsMicrosoft Visual Studio 10.0Common7IDEdevenv” “CZLog.sln” /Rebuild “RELAESE | Win32”
(3)Fortify編譯器配置。
在Windows環(huán)境下,進(jìn)行Fortify檢查也需要區(qū)分兩種不同的情況。
編程使用Visual Studio 2010時(shí),首先需要在Visual Studio 2010 IDE上安裝HP Fortify插件HP_Fortify_SCA_and_Apps_4.00_windows_x86.exe,安裝過(guò)程如下所示:
·將D:ICP_CI_Windows_agentpluginsCodeCC ool下的fortify文件夾備份為fortify_bak,然后新建fortify目錄。
·雙擊HP_Fortify_SCA_and_Apps_4.00_windows_x86.exe進(jìn)行安裝,安裝時(shí)將安裝路徑設(shè)置到在ICP_CI的CodeCC插件的如下路徑:D:ICP_CI_Windows_agentpluginsCodeCC oolfortify。
·在安裝過(guò)程中,需要選擇對(duì)應(yīng)的VS版本,此處選擇“VS2010”。
·在安裝過(guò)程中,還需要選擇license,license文件需要選擇D:ICP_CI_Windows_agentpluginsCodeCC oolfortify_bakfortify.license,其他安裝彈出框選擇“next”即可,安裝完成之后將fortify_bak覆蓋到fortify文件夾下。
·安裝完成之后需要打開(kāi)Visual Studio 2010軟件,查看插件是否已經(jīng)安裝(Visual Studio 2010的菜單欄上有HP Fortify的選項(xiàng)即可)。
為了使Fortify工具可以識(shí)別和使用C/C++程序的編譯器,需要修改Fortify的配置文件,將C/C++程序的編譯器配置到CodeCC oolfortifycoreconfig目錄下的fortify-sca.properties文件中。
編程使用VC6.0和使用Visual Studio 2010的編譯器配置相同,如下所示:
com.fortify.sca.compilers.msdev=com.fortify.sca.util.compilers.DevenvAdapter
com.fortify.sca.compilers.devenv=com.fortify.sca.util.compilers.DevenvNetAdapter
com.fortify.sca.compilers.cl=com.fortify.sca.util.compilers.MicroSoftCompiler
com.fortify.sca.compilers.link=com.fortify.sca.util.compilers.MicrosoftLinker
編譯器配置完成之后,需要將持續(xù)集成主控服務(wù)器與代理服務(wù)器上的fortify工具路徑:pluginCodeCC oolfortifyin添加到環(huán)境變量path中。
(4)Fortify編譯腳本編寫(xiě)。
進(jìn)行代碼編譯時(shí),需要將以前編譯生成的過(guò)程文件與目標(biāo)文件全部刪除。Fortify工具通過(guò)跟蹤編譯器生成中間文件*.nst,如果編譯過(guò)程中以前的過(guò)程文件與目標(biāo)文件沒(méi)有刪除,F(xiàn)ortify工具無(wú)法跟蹤編譯器生成正確的*.nst文件。
為了使Fortify工具通過(guò)跟蹤的方式編譯生成中間文件*.nst,需要根據(jù)軟件模塊重新編寫(xiě)編譯腳本和makefile文件,在編譯腳本中嵌入fortify命令。在編譯過(guò)程中需要調(diào)用鉤子函數(shù)sourceanalyzer.exe文件,將編譯器和鏈接器都掛在鉤子上,從而生成中間文件*.nst。
編程使用VC6.0時(shí)fortify編譯腳本如下所示:
cd/d “D:CodeSecurity_Versionsalm_srcMake PC”
“D:ToolsMicrosoft Visual StudioCommonMSDev98BinMSDEV.exe” “Make PC.dsw” /make “Make PC -win32 RELAESE” /clean
sourceanalyzer -b alm_help_tool_build -clean
sourceanalyzer -b alm_help_tool_build touchless“D:ToolsMicrosoft Visual StudioCommonMSDev98BinMSDEV.exe” “Make PC.dsw” /make “Make PC -win32release” /rebuild
其中,sourceanalyzer表示Fortify工具的執(zhí)行命令主體;build_id表示Fortify的工程名(不能與Fortify的關(guān)鍵字相同)。
編程使用Visual Studio 2010時(shí)fortify編譯腳本如下所示:
cd/d “D:CodeSecurity_VersionsCZLog”
“D:ToolsMicrosoft Visual Studio 10.0Common7IDEdevenv” “CZLog.sln” / clean
sourceanalyzer-b CZLog -Xmx1024M
sourceanalyzer -bCZLog touchless -Xmx1024M “D:ToolsMicrosoft Visual Studio 10.0Common7IDEdevenv” “CZLog.sln” /Rebuild “release | Win32”
由于Visual Studio提供的編譯器對(duì)fortify工具而言屬于標(biāo)準(zhǔn)編譯器,因此在編寫(xiě)fortify腳本時(shí)需要對(duì)調(diào)用sourceanalyzer這個(gè)鉤子函數(shù)采用“無(wú)侵入”式集成[1-2]。“無(wú)侵入”集成對(duì)鉤子函數(shù)在調(diào)用時(shí)有固定格式,具體形式如下:
sourceanalyzer -b
(5)ICP-CI的任務(wù)管理頁(yè)面配置基于C/C++的檢查任務(wù)。
在ICP-CI的任務(wù)管理頁(yè)面的構(gòu)建工程上配置CodeCC檢查任務(wù),通常Coverity任務(wù)和Fortify任務(wù)同時(shí)配置。以基于C/C++的軟件模塊Alm為例來(lái)描述集成過(guò)程。配置Alm模塊的CodeCC任務(wù)時(shí),在任務(wù)欄上選擇“CodeCC”任務(wù)。
對(duì)于Coverity任務(wù),將Alm模塊的編譯腳本alm_help_update_coverity_build.bat和Alm模塊編譯腳本路徑配置到CodeCC任務(wù)類型頁(yè)面下的編譯腳本、編譯路徑中,選擇編譯類型為CL,并在任務(wù)選項(xiàng)欄添加“Coverity”任務(wù)。對(duì)于Fortify任務(wù),將Alm模塊的Fortify編譯腳本alm_help_update_fortify_build.bat以及Alm模塊編譯腳本路徑配置到CodeCC任務(wù)的fortifyexecutable配置項(xiàng)中。最后在任務(wù)類型中添加“Fortify”任務(wù)。CZLog模塊在ICP-CI頁(yè)面上的檢查任務(wù)配置同上。
完成任務(wù)配置之后需要配置檢查結(jié)果的發(fā)送人列表,主送人為該模塊的開(kāi)發(fā)工程師與持續(xù)集成工程師,抄送人為產(chǎn)品經(jīng)理、各開(kāi)發(fā)組長(zhǎng)。
(1)Coverity編譯器配置。
對(duì)于Windows環(huán)境下的Java程序,將編譯器配置在tqeconfig.ini文件中。配置內(nèi)容如下:java=D:Toolsjdkinjavac.exe。
配置過(guò)程也需要根據(jù)實(shí)際安裝路徑來(lái)完成。
完成編譯器配置后,執(zhí)行tqeconfig.bat文件,該文件如果執(zhí)行成功,則將生成相應(yīng)的配置文件保存在CodeCC oolcoverityconfig目錄下。在配置編譯器時(shí)需要注意tqeconfig.bat腳本的執(zhí)行結(jié)果,當(dāng)執(zhí)行窗口中提示執(zhí)行成功,配置的編譯器才能在CodeCC oolcoverityconfig目錄下生成對(duì)應(yīng)編譯器的配置文件。
完成編譯器配置后,需要將持續(xù)集成主控服務(wù)器和代理服務(wù)器上的coverity工具路徑:pluginCodeCC oolcoverityin路徑添加到環(huán)境變量path中。
(2)Coverity編譯腳本編寫(xiě)。
執(zhí)行Coverity任務(wù)時(shí),需要編寫(xiě)相應(yīng)的編譯腳本,使Coverity任務(wù)執(zhí)行時(shí)能夠調(diào)用cov-configure來(lái)編譯Java的工程文件。腳本內(nèi)容如下:
(3)Fortify編譯器配置。
在Windows環(huán)境下,為了使Fortify工具可以識(shí)別和使用Java程序的編譯器,需要修改Fortify的配置文件,將Java程序的編譯器配置到CodeCC oolfortifycoreconfig目錄下的fortify-sca.properties文件中。
Java語(yǔ)言的編譯器配置如下所示:
com.fortify.sca.compilers.javac=com.fortify.sca.util.compilers.javacCompiler
編譯器配置完成之后,需要將持續(xù)集成主控服務(wù)器與代理服務(wù)器上的fortify工具路徑:pluginCodeCC oolfortifyin添加到環(huán)境變量path中。
(4)Fortify編譯腳本編寫(xiě)。
進(jìn)行代碼編譯時(shí),需要將以前編譯生成的過(guò)程文件與目標(biāo)文件全部刪除。Fortify工具通過(guò)跟蹤編譯器生成中間文件*.nst,如果編譯過(guò)程中以前的過(guò)程文件與目標(biāo)文件沒(méi)有刪除,F(xiàn)ortify工具無(wú)法跟蹤編譯器生成正確的*.nst文件。
為了使Fortify工具通過(guò)跟蹤的方式編譯生成中間文件*.nst,需要根據(jù)軟件模塊重新編寫(xiě)編譯腳本和makefile文件,在編譯腳本中嵌入fortify命令。在編譯過(guò)程中需要調(diào)用鉤子函數(shù)sourceanalyzer.exe文件,將編譯器和鏈接器都掛在鉤子上,從而生成中間文件*.nst。
fortify編譯腳本如下所示:
cd/d “D:CodeSecurity_Versions ao_src”
sourceanalyzer -b Nao -Xmx1024M ant -f “D:CodeSecurity_Versions ao_srcuild.xml”
其中,在調(diào)用鉤子函數(shù)sourceanalyzer時(shí),加上-Xmx1024M指令是為了避免分析中間文件時(shí)因內(nèi)存不足導(dǎo)致報(bào)內(nèi)存溢出的錯(cuò)誤,在實(shí)際操作過(guò)程中可以根據(jù)編譯生成中間文件的代理服務(wù)器的系統(tǒng)內(nèi)存,自行設(shè)置這個(gè)值。如果代理服務(wù)器的內(nèi)存不能滿足,可以考慮增加內(nèi)存、更換內(nèi)存較大的代理服務(wù)器來(lái)完成中間文件編譯。
(5)ICP-CI的任務(wù)管理頁(yè)面配置基于Java的檢查任務(wù)。
以基于Java的軟件模塊Nao為例來(lái)描述集成過(guò)程。配置Nao模塊的CodeCC任務(wù)時(shí),在任務(wù)欄上選擇“CodeCC”任務(wù)。對(duì)于Coverity任務(wù),將Nao模塊的編譯腳本build.xml和Nao模塊編譯腳本路徑配置到CodeCC任務(wù)類型頁(yè)面下的編譯腳本、編譯路徑中,選擇編譯類型為JAVAC,并在任務(wù)選項(xiàng)欄添加“Coverity”任務(wù)。對(duì)于Fortify任務(wù),將Nao模塊的Fortify編譯腳本nao_fortify_build.bat以及Nao模塊編譯腳本路徑配置到CodeCC任務(wù)的fortifyexecutable配置項(xiàng)中。最后在任務(wù)類型中再添加“Fortify”任務(wù)。
完成任務(wù)執(zhí)行腳本配置之后需要配置檢查結(jié)果的發(fā)送人列表,主送人為該模塊的開(kāi)發(fā)工程師與持續(xù)集成工程師,抄送人為產(chǎn)品經(jīng)理、各開(kāi)發(fā)組長(zhǎng)。
5.1 CodeCC檢查處理過(guò)程
ICP-CI工具通常先對(duì)模塊做Coverity檢查,生成的中間文件壓縮包上傳到指定的分析服務(wù)器;接著對(duì)模塊做Fortify檢查,同樣將生成的中間文件壓縮包上傳到同一個(gè)分析服務(wù)器。此時(shí)ICP-CI的執(zhí)行窗口顯示CodeCC任務(wù)成功并處于等待分析結(jié)果狀態(tài)。等待分析結(jié)果的時(shí)間長(zhǎng)短取決于生成的中間文件的大小以及分析服務(wù)器的忙碌程度。
當(dāng)分析服務(wù)器分析完畢,將模塊的分析結(jié)果回傳到ICP-CI工具,在ICP-CI工具的頁(yè)面上可以看到Coverity和Fortify工具各自的檢查結(jié)果。檢查結(jié)果包括模塊的缺陷數(shù)以及總?cè)毕輸?shù),缺陷級(jí)別。缺陷級(jí)別分為高、中、低3個(gè)級(jí)別。同時(shí)根據(jù)檢查模塊任務(wù)配置的郵件主送人和抄送人,給這些人發(fā)送郵件。郵件內(nèi)容為該檢查模塊的Coverity和Fortify檢查日志與檢查結(jié)果下載路徑。
對(duì)檢查出來(lái)的各種問(wèn)題,需要開(kāi)發(fā)人員下載檢查結(jié)果文件,并對(duì)檢查結(jié)果與模塊源代碼進(jìn)行分析。確認(rèn)是源代碼問(wèn)題,修改源代碼后重新合入版本庫(kù),啟動(dòng)新一輪的CodeCC檢查;根據(jù)新的檢查結(jié)果確認(rèn)代碼缺陷是否已經(jīng)被解決,已經(jīng)解決掉的缺陷呈現(xiàn)的狀態(tài)為“Fixed”,呈現(xiàn)狀態(tài)為“new”缺陷數(shù)量減少。分析之后,確認(rèn)是誤報(bào)的缺陷,從ICP-CI上顯示的Coverity和Fortify工具檢查結(jié)果頁(yè)面的“Ignore defects”鏈接進(jìn)入由分析服務(wù)器指定的缺陷庫(kù)完成誤報(bào)缺陷的屏蔽,屏蔽之后的缺陷呈現(xiàn)為“Dismissed”狀態(tài)。當(dāng)執(zhí)行下一次CodeCC檢查時(shí),分析結(jié)果的缺陷數(shù)也會(huì)減少。
5.2 CodeCC檢查失敗的分析和處理
進(jìn)行CodeCC檢查時(shí),難免會(huì)出現(xiàn)失敗的情況。CodeCC檢查失敗需要及時(shí)發(fā)現(xiàn)處理,根據(jù)已經(jīng)失敗的模塊、構(gòu)建工程頁(yè)面上提示失敗的信息和構(gòu)建工程的詳細(xì)日志文件,來(lái)確定該模塊CodeCC檢查失敗的原因,并確定解決問(wèn)題的方案。
5.2.1 Coverity或Fortify檢查在編譯階段出錯(cuò)
在編譯階段出錯(cuò),查看對(duì)應(yīng)的編譯日志可以發(fā)現(xiàn)各種問(wèn)題(編譯器配置問(wèn)題、編譯腳本問(wèn)題或源代碼編譯錯(cuò)誤等),導(dǎo)致在編譯階段Coverity或Fortify檢查報(bào)錯(cuò)。
解決方法如下:
(1)在tqeconfig.ini中配置相應(yīng)編譯器,并執(zhí)行tqeconfig.bat文件完成配置,或在fortify-sca.properties文件中完成配置。
(2)根據(jù)日志所報(bào)編譯問(wèn)題,重新編寫(xiě)編譯模塊的編譯腳本。
(3)開(kāi)發(fā)工程師定位模塊編譯錯(cuò)誤,修改后的源代碼合入版本庫(kù)之后重新執(zhí)行模塊的CodeCC檢查任務(wù)。
5.2.2 Coverity或Fortify檢查在分析階段出錯(cuò)
在分析階段出錯(cuò),查看對(duì)應(yīng)的分析日志可以發(fā)現(xiàn)大部分是分析服務(wù)器問(wèn)題導(dǎo)致的執(zhí)行失敗,通常表現(xiàn)為上傳中間文件壓縮包失敗、分析結(jié)果回傳失敗等。根據(jù)分析日志發(fā)現(xiàn)此類問(wèn)題,需要聯(lián)系CodeCC工具運(yùn)維工程師和相關(guān)人員解決分析服務(wù)器問(wèn)題。
5.2.3 CodeCC檢查文件的比例問(wèn)題
此類問(wèn)題需要查看Coverity檢查的編譯日志文件build.log,在該文件的結(jié)尾部分查看模塊編譯檢查文件的百分比,如果模塊編譯的文件都完成檢查,那么檢查文件的百分比應(yīng)該是100%。如果這個(gè)百分比值小于100%,需要查找錯(cuò)誤。通常這些錯(cuò)誤不是產(chǎn)品模塊的代碼編譯錯(cuò)誤,而是Coverity檢查時(shí)產(chǎn)品模塊源代碼生成中間文件過(guò)程中與編譯器沖突導(dǎo)致的。為了提高檢查的文件比例,需要開(kāi)發(fā)工程師與系統(tǒng)工程師進(jìn)行分析,盡可能通過(guò)修改的源代碼進(jìn)一步提高檢查文件的比例。
某公司有一個(gè)軟、硬件結(jié)合的大型開(kāi)發(fā)項(xiàng)目。采用的軟件配置管理工具為SVN,持續(xù)集成工具為ICP-CI。1臺(tái)主控服務(wù)器和8臺(tái)代理服務(wù)器參與CodeCC檢查。Windows操作系統(tǒng)的版本是Windows 7。采用Visual Studio 2010進(jìn)行C++程序設(shè)計(jì)。采用Eclipse 3.6進(jìn)行Java程序設(shè)計(jì)。采用的Coverity工具版本為6.5.3;Fortify工具版本為6.00.0096。集成到ICP-CI工具后,使用Shell腳本和ANT腳本完成對(duì)軟件模塊的Coverity檢查和Fortify檢查。
以C++的Alm模塊與CZLog模塊為例,對(duì)該模塊進(jìn)行檢查的掃描結(jié)果如表1所示。
以Java的Nao模塊為例,對(duì)該模塊進(jìn)行檢查的掃描結(jié)果如表2所示。
表1 對(duì)Alm工具進(jìn)行Coverity檢查和Fortify檢查的掃描結(jié)果
表2 對(duì)Nao工具進(jìn)行Coverity檢查和Fortify檢查的掃描結(jié)果
檢查結(jié)果報(bào)告中分別給出了Coverity檢查和Fortify檢查的告警級(jí)別、告警數(shù)量,并詳細(xì)列舉了缺陷的類型與種類。開(kāi)發(fā)工程師通過(guò)下載檢查結(jié)果報(bào)告,對(duì)產(chǎn)品源代碼進(jìn)行分析和處理。經(jīng)過(guò)對(duì)Alm模塊和Nao模塊的代碼優(yōu)化、重構(gòu)以及誤報(bào)告警屏蔽,最終將Alm模塊和Nao模塊的告警數(shù)目清零,修正了模塊源代碼存在的缺陷,改進(jìn)了模塊的源代碼質(zhì)量。
工作實(shí)踐表明,重量級(jí)靜態(tài)檢查有助于及時(shí)發(fā)現(xiàn)并解決C/C++與Java軟件源代碼的各種缺陷,便于產(chǎn)品主管了解工作進(jìn)度和解決存在的問(wèn)題,進(jìn)一步提升產(chǎn)品質(zhì)量。
長(zhǎng)期的工作實(shí)踐表明,在Windows環(huán)境下進(jìn)行C/C++和Java軟件開(kāi)發(fā),Coverity和Fortify組成的重量級(jí)靜態(tài)檢查工具在開(kāi)發(fā)過(guò)程中發(fā)揮了重要作用。檢查工具集成到持續(xù)集成工具ICP-CI,可以自動(dòng)完成檢查,快速地向軟件開(kāi)發(fā)人員反饋檢查結(jié)果,使軟件開(kāi)發(fā)人員能夠及時(shí)修復(fù)源代碼的缺陷,同時(shí)也給項(xiàng)目管理提供了很好的保證。在軟件開(kāi)發(fā)過(guò)程中做好靜態(tài)檢查工作將在很大程度上提高產(chǎn)品的質(zhì)量,降低軟件開(kāi)發(fā)的成本。
[1] 白 喬,左 飛.把脈VC++[M].北京:電子工業(yè)出版社,2009.
[2] 張立勇,劉 堅(jiān),陳 平.C/C++程序的靜態(tài)安全分析[J].系統(tǒng)工程與電子技術(shù),2008,30(6):1155-1158.
[3] 張 峰.Java程序設(shè)計(jì)與項(xiàng)目實(shí)戰(zhàn)[M].北京:清華大學(xué)出版社,2011.
[4] 趙 平.JAVA源代碼靜態(tài)分析系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].長(zhǎng)春:吉林大學(xué),2013.
[5] Stiehm T,Gotimer G.Building security in using continuous integration[J].The Journal of Defense Software Engineering,2010,23(2):24-27.
[6] 路曉波.軟件開(kāi)發(fā)過(guò)程中白盒測(cè)試方法和工具的研究及應(yīng)用[D].南京:南京郵電大學(xué),2012.
[7] 吳世忠,郭 濤,董國(guó)偉,等.軟件漏洞分析技術(shù)[M].北京:科學(xué)出版社,2014.
[8] Almossawi A,Lim K,Sinha T.Analysis tool evaluation:coverity prevent[R].[s.l.]:Carnegie Mellon University,2006.
[9] Coverity? 6.6deployment guide planning,installation,tuning,and supported platforms[R].[s.l.]:Coverity Inc,2013.
[10] Coverity? scan:2013 open source report[R].[s.l.]:Coverity Inc,2014.
[11] Coverity? scan open source report 2014[R].[s.l.]:Synopsys Inc,2015.
[12] Fortify source code analyzer用戶指南(版本5.1)[M].[s.l.]:Fortify Software Inc,2008.
[13] Fortify SCA user guide fortify 360 version 2.6[M].[s.l.]:Fortify Software Inc,2010.
[14] Blay P,Corlett S.Fortify SCA performance guide[M].[s.l.]:Fortify Software Inc,2014.
[15] Fortify source code analysis suite tutorial[M].[s.l.]:Fortify Software Inc,2010.
[16] 羅時(shí)飛.敏捷持續(xù)集成(CruiseControl版):高效硏發(fā)之道[M].北京:電子工業(yè)出版社,2008.
Heavy-weight Static Checking of Software in C/C++ and Java
JIANG Wen,LIU Li-kang
(School of Telecommunication Engineering,Xidian University,Xi’an 710071,China)
In order to ensure the quality of code in language C/C++ and Java based on Windows,it is very important for the static checking to code of C/C++ and Java.With SVN as configuration management tool,the heavy-weight static checking tools Coverity and Fortify are integrated into continuous integration tool ICP-CI,and static checking is to be done for both C/C++ and Java.The SVN client installation and the code updating of the SVN repository under Windows is described in details,and the Coverity and Fortify compiler configuration,the compiler scripts writing,and the inspection tasks configuration on ICP-CI task management page are conducted for both C/C++ and Java.The process of the static checking is introduced and the causes of problems are analyzed and the corresponding solutions are given.Finally the heavy-weight static checking applied in a case for both modules of code in C/C++ and Java in software product is introduced.Practice shows that the static checking is helpful to discover and solve all kinds of flaws of the code in C/C++ and Java timely,improving quality and safety for software.
Windows operating system;static checking;continuous integration;security vulnerabilities
2015-12-12
2016-04-05
時(shí)間:2016-08-01
國(guó)家部委基礎(chǔ)科研計(jì)劃:國(guó)防預(yù)研基金項(xiàng)目(A1120110007)
姜 文(1986-),女,工程師,碩士,CCF會(huì)員,研究方向?yàn)閳D像處理與分析、數(shù)據(jù)庫(kù)應(yīng)用和軟件工程;劉立康,副教授,研究方向?yàn)閿?shù)字通信、圖像傳輸與處理、圖像分析與識(shí)別等。
http://www.cnki.net/kcms/detail/61.1450.TP.20160801.0907.054.html
TP311.56
A
1673-629X(2016)08-0017-07
10.3969/j.issn.1673-629X.2016.08.004