C++編程語(yǔ)言在嵌入式應用中的安全問(wèn)題
在嵌入式系統的軟件設計中,“匯編語(yǔ)言+C語(yǔ)言”早已成為理所當然的經(jīng)典組合。的確,對于硬件配置來(lái)說(shuō),匯編語(yǔ)言清晰明了;對于上層設計來(lái)說(shuō),C語(yǔ)言緊湊高效。這樣的搭配能夠滿(mǎn)足大多數傳統嵌入式系統應用的需要。隨著(zhù)技術(shù)水平的提高,今天的嵌入式系統也比過(guò)去更加深入到人們的日常生活中,大到汽車(chē)、飛機、火箭,小到手機、打印機、鬧鐘、手表,都可以找到嵌入式系統的蹤影。然而,這看似一成不變的情況,也在悄然轉變。隨著(zhù)網(wǎng)絡(luò )、多媒體等技術(shù)的出現、發(fā)展與普及,對嵌入式系統應用有了新的要求,也給了其他高級語(yǔ)言,特別是C++語(yǔ)言以機會(huì )。
由此帶來(lái)的在語(yǔ)言使用中的安全問(wèn)題,目前雖然還未凸顯,但根據以往的經(jīng)驗來(lái)看,終將成為限制行業(yè)發(fā)展的新瓶頸。已有的C++語(yǔ)言國際標準雖然龐大細致,但作為一個(gè)“語(yǔ)言標準”,只能是盡力做得面面俱到,其目標在于構造一個(gè)語(yǔ)句合法性的權威依據,以約束人們對于C++的使用。但它并不是針對應用而寫(xiě)的規范,對于可能遇到的安全性問(wèn)題也無(wú)法進(jìn)行特別深入的探討,更加沒(méi)有安全方面的實(shí)踐經(jīng)驗支撐。一個(gè)針對安全方面的、被國際所認可的使用規范,無(wú)疑是C++語(yǔ)言在嵌入式系統中得到廣泛應用的堅實(shí)基礎與助推劑。
1 C++在嵌入式應用中的機遇與挑戰
C++作為一門(mén)高級語(yǔ)言,人們在提及它時(shí),總難免會(huì )談到C語(yǔ)言。直至今天,很多人對于C++語(yǔ)言的認識依然是“C語(yǔ)言的超集”。這是因為C++的起源與C語(yǔ)言有著(zhù)千絲萬(wàn)縷的聯(lián)系。
1978年,美國貝爾實(shí)驗室的Dennis Ritchie和BrianKernighan在BCPL以及其簡(jiǎn)化版本B語(yǔ)言的基礎之上開(kāi)發(fā)了C語(yǔ)言,并合作出版了《The C Programming Lan-guage》。C語(yǔ)言迅速得到了大家的認可,并廣為流傳。1989年,ANSI推出了第一個(gè)C語(yǔ)言的標準——X3.159-1989,并被ISO采納,隨之發(fā)布。ISO/IEC 9899-1990。早在C語(yǔ)言標準發(fā)布之前,貝爾實(shí)驗室的Bjarne Stroustrup就致力于在C語(yǔ)言里增加類(lèi)、函數類(lèi)型檢查以及其他的一些優(yōu)秀特征,于1980年發(fā)布“C with Classes”。經(jīng)過(guò)持續的努力,他最終完成了對C語(yǔ)言的改造,由此創(chuàng )生出一門(mén)新語(yǔ)言——C++,并出版了《The C++ ProgrammingLanguage》一書(shū)。由于它帶來(lái)了持續的影響,ISO于1998年發(fā)布ISO/IEC 14882:1998;幾乎同一時(shí)間,ANSI也發(fā)布了類(lèi)似標準,這標志著(zhù)C++作為一門(mén)獨立語(yǔ)言的標準化得到了官方的認可。
統計數據表明,日常生活中一個(gè)美國人平均占用8個(gè)微控制器,這些都離不開(kāi)嵌入式系統的應用。然而嵌入式系統軟件技術(shù)似乎落后于當前的軟件發(fā)展形勢,近年來(lái)才逐漸由匯編語(yǔ)言過(guò)渡到面向過(guò)程的C語(yǔ)言。但對于面向對象語(yǔ)言的應用還很有限。
這一方面是由于嵌入式開(kāi)發(fā)人員多年來(lái)應付有限資源的經(jīng)驗而養成的保守態(tài)度,另一方面也是由于長(cháng)久以來(lái),嵌入式系統應用設計中,人們要花費許多精力在底層硬件的驅動(dòng)上,功能實(shí)現也主要局限在實(shí)時(shí)操作系統和相關(guān)支撐軟件的層次,并不涉及過(guò)多的應用軟件開(kāi)發(fā)。這種在嚴苛條件下追求效率與實(shí)時(shí)性的任務(wù),其他的高級語(yǔ)言并沒(méi)有特別的優(yōu)勢。
最近幾年,嵌入式系統領(lǐng)域又有了新的發(fā)展。首先,隨著(zhù)手機、PDA等消費性電子產(chǎn)品的飛速增長(cháng),嵌入式系統的市場(chǎng)規模在迅速擴大,同時(shí)越來(lái)越多的智能嵌入式應用場(chǎng)合需要互聯(lián)網(wǎng)的支持,這要求嵌入式系統的軟件具有更好的應用性和更高的復雜性;其次,隨著(zhù)芯片等相關(guān)領(lǐng)域的技術(shù)進(jìn)步,嵌入式系統工程師們不再需要時(shí)時(shí)刻刻去考慮資源是否夠用了。當面向對象的高級語(yǔ)言參與到嵌入式系統設計中去不再遙不可及時(shí),語(yǔ)言的效率則成為突出的問(wèn)題。根據《Thinking in C++》一書(shū)的總結,C++與C的效率差別往往在±5%,這使得C++在新一輪的嵌入式應用發(fā)展浪潮中占得先機。
值得注意的是,盡管自1998年發(fā)布最初的C++標準——ISO/IEC 14882:1998以來(lái),每5年都會(huì )對此標準進(jìn)行一次更新,但是由于C++語(yǔ)言過(guò)于復雜,以及它經(jīng)歷了長(cháng)年的演變,直到2004年,沒(méi)有任何一款編譯器完全支持ISO C++。這對于時(shí)常要面對各種嚴苛條件的嵌入式系統應用工程師們來(lái)說(shuō),是難以忍受的。同時(shí),即使是符合ISO C++標準的語(yǔ)句或者格式,對于實(shí)際的應用場(chǎng)合來(lái)說(shuō),也存在著(zhù)重大隱患,而不應當被直接采用。因此,人們迫切需要一個(gè)正式的基于安全角度考慮的C++語(yǔ)言使用規范。
2 關(guān)于MISRA
MISRA(the Motor Industry Software Reliability As-sociation),即汽車(chē)工業(yè)軟件可靠性協(xié)會(huì ),于1994.年在英國成立,以“協(xié)助汽車(chē)工業(yè)提供安全、可靠的軟件”為使命,期望通過(guò)“規范指南”的形式來(lái)約束人們在汽車(chē)電子以及其他嵌入式系統開(kāi)發(fā)領(lǐng)域或涉及安全與可靠性的領(lǐng)域中對于程序語(yǔ)言的使用。由于這些“規范指南”都是從大量工程實(shí)踐中總結的第一手經(jīng)驗,因而具有極高的指導意義。
經(jīng)過(guò)4年準備,它在1998年發(fā)布了一個(gè)針對汽車(chē)工業(yè)的《Guidelines for the Use of the C Langtlage in VehicleBased Software》,簡(jiǎn)稱(chēng)“MISRA C:1998'’,針對那些滿(mǎn)足C語(yǔ)言標準,卻存在安全隱患的語(yǔ)言使用習慣,提出了127條規則。由于它很好地解決了C語(yǔ)言國際標準的冗繁性,以及其中對于安全性考慮的不足性,從而得到了廣泛的好評。MISRA-C不僅成為眾多汽車(chē)廠(chǎng)商推崇的行業(yè)標準,其影響力更是遠遠超出了汽車(chē)工業(yè),得到鐵路、航空航天、國防、醫療等眾多領(lǐng)域的認可,成為“最佳實(shí)踐”解決方案。2004年,MISRA對于已有的規則進(jìn)行改編與擴充,推出了“MISRA C 2004”,首次將該規范指南的對象從汽車(chē)工業(yè)推廣到所有具有安全性要求的系統應用中去,包含了強制規則121條,推薦規則20條,并刪除了15條舊規則,共計含有141條規則。
時(shí)至今日,MISRA組織不僅是汽車(chē)工業(yè)軟件規范的權威,其制定的規范指南更得到了嵌入式系統應用領(lǐng)域的廣泛認可??紤]到近年來(lái),C++語(yǔ)言在嵌入式系統中的應用越來(lái)越多,2005年MISRA C++委員會(huì )成立,并于2008年推出針對C++語(yǔ)言的《MISRA C++:2008——Guidelines for the USe of the C++ language in critical sys-tems>>,以下簡(jiǎn)稱(chēng)“MISRA C++:2008”。有興趣的讀者可以聯(lián)系相關(guān)網(wǎng)站:http://www.misra-cpp.com/,購買(mǎi)詳細的文檔。
MISRA C++:2008同樣從推出之日起,就得到了業(yè)內外廣泛關(guān)注。例如:LDRA軟件公司一直跟蹤著(zhù)MIS-RA C++:2008的制定進(jìn)展,在MISRA C++:2008發(fā)布時(shí)同步宣稱(chēng)已經(jīng)完成了對工具套件產(chǎn)品的相應改進(jìn),使其符合MISRA C++:2008標準。(LDRA的Testbed產(chǎn)品曾成功用于“神舟”飛船項目的軟件測試)。
3 MISRA C++概述
作為規范指南,MISRA C++:2008基于ISO/IEC 14882:2003的C++語(yǔ)言國際標準,以規則(rule)的形式,給出了相關(guān)的建議。它的規則又細分為以下3種類(lèi)型:
①強制型(required),必須符合、允許例外;
②推薦型(advisory),推薦符合;
③不容討論型(document),必須符合、不許例外。
MISRA C++:2008中共給出了20個(gè)大類(lèi)的規則(編號并不連續),細分為228條。詳細情況如表1所列。
文檔中所有規則的書(shū)寫(xiě)格式如下:
每條規則之后都有詳細的解釋?zhuān)⒔o出了一些具體的程序語(yǔ)句作為例子。下面分別針對上述3種規則類(lèi)別,進(jìn)行舉例說(shuō)明。
規則0-1-1(強制)工程中不允許包含無(wú)法觸及的代碼
上述例子里,條件判斷中的賦值語(yǔ)句和return語(yǔ)句之后的自增語(yǔ)句都是在任何條件下都無(wú)法觸及的死代碼,不允許這樣使用。
規則0-1-2 (強制) 工程中不允許含有永遠不會(huì )被執行的路徑
enum ec{RED,BLUE,GREEN)col;
if(col=GREEN) //不符合規則,條件永遠為真
{
//Will always get,here
}
else
{
//代碼永遠不會(huì )到達這里
}
由于枚舉類(lèi)型有默認的初始賦值0,1,2,…,故col永遠≤GREEN。上述例子中,含有任何條件下都不會(huì )被執行的路徑,不允許這樣使用。
規則5-2-10(推薦) 自增(++)/自減(--)運算符不應與表達式中其他運算符混合使用諸如下面的例程將導致理解上的混淆以及結果的不確定,在程序設計時(shí)應盡可能避免。
u8a=++u8b+u8c-; //不符合規則
規則0-4-2 (不容討論) 對于浮點(diǎn)運算(floating-point)算法的使用,必須給出記錄
安全的使用浮點(diǎn)算法需要具有較高的數字分析技能和對編譯器及硬件對象的深入了解。因此在使用浮點(diǎn)算法時(shí),必須先進(jìn)行分析:是否必須使用它、采取的方法是否可行、過(guò)程是否得到了正確的執行,并將上述結果做出記錄。
規則16-6-1 (不容討論) 所有的庫函數代碼必須符合MISRA C++。
上述這些例子只是為了讓大家對MISRA C++:2008的3種規則有一定的認識,我們會(huì )結合相關(guān)內容,在接下來(lái)的幾篇文章中進(jìn)一步討論學(xué)習。不難發(fā)現,許多違反了MISRA C++:2008中規則的例程都是符合C++語(yǔ)言標準的,但出于安全性考慮,應當被禁止或者謹慎使用。通覽之后,往往會(huì )發(fā)現自己平時(shí)從未注意的一些編程習慣,都已經(jīng)被嚴令禁止。它們有些是明顯有礙安全性的,有些則相對隱蔽。
然而MISRA的號召力是不容小覷的。以嵌入式實(shí)時(shí)操作系統μC/OS-II為例,其2.52版本雖然已經(jīng)于2000年通過(guò)了美國航空管理局(FAA)的安全認證,但2003年μC/OS-II的作者就根據MISRA C:1998規范又對源碼作了相應的修改,并發(fā)布了2.62的新版本,宣稱(chēng)其源代碼99%符合MISRA C:1998的要求。
4 安全性問(wèn)題
對于安全性,MISRA給出以下5種可能的安全問(wèn)題來(lái)源:開(kāi)發(fā)人員的錯誤、開(kāi)發(fā)人員對于語(yǔ)言的誤解、編譯器沒(méi)有按照開(kāi)發(fā)人員的預期工作、編譯器本身含有錯誤、運行錯誤。
這些錯誤的來(lái)源與實(shí)際使用的是何種計算機語(yǔ)言沒(méi)有關(guān)系,可以說(shuō)比較全面地包含了嵌入式系統開(kāi)發(fā)以及其他相關(guān)的軟件設計中可能導致安全問(wèn)題的所有渠道。
作為C++這樣一門(mén)面向對象的高級語(yǔ)言(由于其與C的淵源,嚴格地說(shuō),C++是具有某些面向對象特征的過(guò)程語(yǔ)言),通過(guò)類(lèi)、函數參數類(lèi)型檢查、模版、異常處理以及派生、繼承、多態(tài)等手段,使得其在保有高效率的同時(shí),實(shí)現了強大的功能,并帶來(lái)了自頂向下的模塊化程序設計理念。但編程靈活度的提高,也令其代碼復雜而易錯。與C語(yǔ)言相比,它所面對的安全問(wèn)題將更為隱蔽,更加難以發(fā)現。但就對數據的封裝而言,C++遠遠優(yōu)于C,只要參照合理的規范指南,進(jìn)行項目的開(kāi)發(fā),就可以通過(guò)充分發(fā)揮C++靈活的特點(diǎn),應用到更多更廣的工程領(lǐng)域。
5 行業(yè)展望
標準與規范從來(lái)沒(méi)有如眼下這般備受重視過(guò)。一個(gè)權威的標準或規范,不僅將成為相關(guān)領(lǐng)域的“金科玉律”,更是行業(yè)動(dòng)向的風(fēng)向標??梢哉f(shuō)正是由于MISRA-C的存在,使得在高級語(yǔ)言種類(lèi)繁多的今天,C語(yǔ)言的地位依然無(wú)可替代。
此次MISRA攜著(zhù)在C語(yǔ)言上的巨大成功,選擇了C++語(yǔ)言進(jìn)行新的規范化嘗試,不僅因為C++語(yǔ)言的群眾基礎深厚,更是表明了嵌入式系統領(lǐng)域內大多數專(zhuān)家的觀(guān)點(diǎn):如果說(shuō)未來(lái)能有一門(mén)語(yǔ)言取代目前C語(yǔ)言在嵌入式系統應用中的地位的話(huà),也只能是C++語(yǔ)言。一名成功的嵌入式系統工程師,必須是對行業(yè)動(dòng)向極為敏感的,也只有這樣,才能在知識爆炸的今天緊跟時(shí)代潮流。從使用C語(yǔ)言到使用C++語(yǔ)言是一個(gè)巨大的跨越,決不僅僅像使用“增強的C”那么簡(jiǎn)單,需要從現在就開(kāi)始學(xué)習。而從學(xué)習之初就養成的良好的語(yǔ)言使用習慣,將決定將來(lái)進(jìn)階的速度與可能性。MISRA C++:2008無(wú)疑是培養這樣良好習慣的最佳手冊。
評論