小組討論圍繞著適合內(nèi)核開發(fā)的替代更安全的語(yǔ)言(如 Ada 和 Rust),以及形式驗(yàn)證的需求超出了編譯器可以提供的保證。事實(shí)上,目前在 Linux 內(nèi)核上報(bào)告的許多內(nèi)存和安全漏洞會(huì)在 Ada 或 Rust 中完全停止程序,這只是稍微好一點(diǎn)。查看內(nèi)核補(bǔ)丁可以發(fā)現(xiàn),通過(guò)在代碼上指定簡(jiǎn)單屬性可以檢測(cè)到許多問(wèn)題,例如哪些調(diào)用在哪種模式下是合法的、應(yīng)該保留的數(shù)據(jù)不變量的類型以及如何使用適當(dāng)?shù)墓ぞ哽o態(tài)驗(yàn)證它們。
令人驚訝的是,在討論中根本沒(méi)有提到 MISRA C,盡管它已成為許多行業(yè)的必備工具,以防止 C 語(yǔ)言的錯(cuò)誤。MISRA C 于 1998 年作為 C 的編碼標(biāo)準(zhǔn)出現(xiàn),最初用于汽車行業(yè),經(jīng)過(guò)兩次修訂。當(dāng)前版本是 MISRA C:2012。它側(cè)重于避免 C 編程語(yǔ)言容易出錯(cuò)的特性,而不是強(qiáng)制執(zhí)行特定的編程風(fēng)格。Les Hatton編寫的 C 編碼標(biāo)準(zhǔn)研究發(fā)現(xiàn),與十種典型的 C 編碼標(biāo)準(zhǔn)相比,MISRA C 是唯一一個(gè)專注于避免錯(cuò)誤而不是風(fēng)格強(qiáng)制的標(biāo)準(zhǔn),而且差距很大。
C 編程語(yǔ)言的流行,以及它的許多陷阱和陷阱,導(dǎo)致 MISRA C 在 C 用于高完整性軟件的領(lǐng)域中取得巨大成功。這一成功促使工具供應(yīng)商提出了許多相互競(jìng)爭(zhēng)的 MISRA C 檢查器實(shí)施方案。工具尤其在它們幫助執(zhí)行的 MISRA C 指南的覆蓋范圍內(nèi)競(jìng)爭(zhēng),因?yàn)椴豢赡軋?zhí)行 MISRA C 的所有 16 條指令和 143 條規(guī)則(統(tǒng)稱為指南)。
特別是,143 條規(guī)則中有 27 條是不可判定的,因此沒(méi)有任何工具能夠始終檢測(cè)到所有違反這些規(guī)則的行為,而不同時(shí)對(duì)不構(gòu)成違規(guī)的代碼報(bào)告“錯(cuò)誤警報(bào)”。不可判定規(guī)則的一個(gè)例子是規(guī)則 1.3:“不得發(fā)生未定義或關(guān)鍵的未指定行為”。MISRA C:2012 的附錄 H 列出了 C 編程語(yǔ)言標(biāo)準(zhǔn)中數(shù)百個(gè)未定義和關(guān)鍵未指定行為的案例,其中大多數(shù)無(wú)法單獨(dú)確定。在大多數(shù)情況下,MISRA C 檢查器會(huì)忽略無(wú)法確定的規(guī)則,例如規(guī)則 1.3,盡管眾所周知,違反這些規(guī)則會(huì)對(duì)軟件質(zhì)量產(chǎn)生巨大影響。
但是,對(duì)于其他編程語(yǔ)言,可以使用靜態(tài)分析技術(shù)來(lái)應(yīng)對(duì)這一挑戰(zhàn),而不會(huì)因誤報(bào)而淹沒(méi)用戶。一個(gè)例子是由 AdaCore、Altran 和 Inria 開發(fā)的 SPARK 工具集,它基于四個(gè)原則:
基礎(chǔ)語(yǔ)言 Ada 通過(guò)定義明確的語(yǔ)言標(biāo)準(zhǔn)、強(qiáng)類型和豐富的規(guī)范特性為靜態(tài)分析提供了堅(jiān)實(shí)的基礎(chǔ)。
Ada 的 SPARK 子集通過(guò)控制歧義的來(lái)源(例如函數(shù)的副作用和名稱的別名)以支持靜態(tài)分析的基本方式限制了基礎(chǔ)語(yǔ)言。
靜態(tài)分析工具主要以單個(gè)函數(shù)的粒度工作,使分析更加精確,并最大限度地減少誤報(bào)的可能性。
靜態(tài)分析工具是交互式的,允許用戶在必要或需要時(shí)指導(dǎo)分析,并在用戶提供的合約無(wú)法證明時(shí)提供反例。
SPARK 可以在 C 代碼庫(kù)中逐步采用,通過(guò)SPARK 采用的五個(gè)級(jí)別逐步獲得保證,并通過(guò)支持將形式分析 (SPARK) 與傳統(tǒng)的基于測(cè)試的方法 (C) 相結(jié)合的“混合驗(yàn)證”。
SPARK Stone Level - 基本保證
SPARK 采用的第一級(jí)稱為 Stone Level。它對(duì)應(yīng)于符合 Ada 的 SPARK 子集的代碼。僅僅采用這個(gè)級(jí)別就可以保證許多 C 語(yǔ)言無(wú)法強(qiáng)制執(zhí)行的一致性屬性。其中包括:
使用適當(dāng)?shù)陌到y(tǒng),而不是 C 使用基于文本的文件包含,并且沒(méi)有跨翻譯單元的一致性要求;
嚴(yán)格和可讀的語(yǔ)法,強(qiáng)調(diào)清晰并最大限度地減少“陷阱”,而不是 C 的非常寬松的語(yǔ)法,這使得編寫效果不是預(yù)期的程序變得容易,
遵守 Ada 和 SPARK 的強(qiáng)類型規(guī)則,而不是 C 的“較差的類型安全性 [that] 允許發(fā)生廣泛的隱式類型轉(zhuǎn)換 [which] 可能會(huì)損害安全性,因?yàn)樗鼈兊膶?shí)現(xiàn)定義方面可能會(huì)導(dǎo)致開發(fā)人員混淆。 “(MISRA C:2012,附件 C)
MISRA C 試圖通過(guò)各種指導(dǎo)來(lái)馴服 C 語(yǔ)言的這些可能的不一致。它特別定義了更強(qiáng)的類型規(guī)則(“基本類型模型”)并限制函數(shù)參數(shù)/結(jié)果和控制結(jié)構(gòu)的使用。雖然這些避免了開發(fā)人員混淆的常見(jiàn)來(lái)源,但它們故意不是防彈的,否則它們會(huì)使大多數(shù) C 程序非法。
由于定義了 Ada 的 SPARK 子集的更強(qiáng)大的規(guī)則,這些基本保證很容易在 SPARK 中通過(guò)一個(gè)名為 GNATprove 的工具進(jìn)行類似編譯器的簡(jiǎn)單分析來(lái)實(shí)現(xiàn)。
SPARK 銀級(jí) - 強(qiáng)大的安全保障
MISRA-C 指南還旨在防止更細(xì)微的錯(cuò)誤、未初始化數(shù)據(jù)的讀取、表達(dá)式中的沖突副作用以及未定義的行為,例如除以零或緩沖區(qū)溢出(可能具有安全性和安全性后果)。所有這些都屬于不可判定規(guī)則的范疇,很少有 MISRA C 檢查器能提供完整的檢測(cè)。
這些在 SPARK 采用的 Silver 級(jí)別上完全被阻止,這對(duì)應(yīng)于使用流分析(達(dá)到 SPARK 采用的第二級(jí),稱為 Bronze)和不存在運(yùn)行時(shí)錯(cuò)誤的證明(達(dá)到第三級(jí),即銀)。為了達(dá)到這個(gè)水平,開發(fā)人員通常需要定義具有特定約束的類型,這些約束旨在支持和提供文件之間導(dǎo)出的函數(shù)的合同——使用所謂的前置條件來(lái)指定調(diào)用者的義務(wù),并使用后置條件來(lái)指定調(diào)用者的義務(wù)。被叫方的義務(wù)。
達(dá)到 Silver 級(jí)別的過(guò)程涉及與 IDE 的交互。開發(fā)人員可能在程序的一個(gè)子集上運(yùn)行 GNATprove 工具,調(diào)查 GNATprove 診斷,相應(yīng)地更新程序,然后重復(fù)。GNATprove 在每一步都提供了詳細(xì)的信息來(lái)指導(dǎo)開發(fā)人員,從而促進(jìn)了此類交互。以下是 GNATprove 顯示的消息示例:

在找到可能導(dǎo)致溢出的加法運(yùn)算后,GNATprove 給出了一個(gè)觸發(fā)問(wèn)題的值的示例,這里是最大的 Integer 值(在 SPARK 中表示為 Integer‘Last)。“檢查原因”清楚地解釋了加法的結(jié)果應(yīng)該適合機(jī)器整數(shù),如果 X 是加法之前的最大整數(shù)值,則情況并非如此。然后,GNATprove 建議向函數(shù) Incr 添加合適的前提條件可能會(huì)解決問(wèn)題,方法是在此處指定 X 不能是那個(gè)最大值。
SPARK 超越白銀級(jí)
使用 SPARK 還有其他好處,遠(yuǎn)遠(yuǎn)超出 MISRA C 檢查器所能提供的。在 Gold 和 Platinum 級(jí)別,開發(fā)人員通過(guò) SPARK 合同指定程序的屬性,然后可以使用 GNATprove 來(lái)保證這些屬性將得到滿足。開發(fā)人員還可以啟用 GNATprove 警告以檢測(cè)死代碼(也是 MISRA C 追求的目標(biāo))和代碼中的不一致,使用構(gòu)成 GNATprove 分析基礎(chǔ)的強(qiáng)大證明技術(shù)。
結(jié)論
從本質(zhì)上講,MISRA C 追求的所有目標(biāo)都在 SPARK 中得到了最好的實(shí)現(xiàn),結(jié)合了更強(qiáng)大的基礎(chǔ)語(yǔ)言 (Ada) 和強(qiáng)大的分析工具 (GNATprove)。計(jì)劃使用 MISRA C 規(guī)則的開發(fā)人員可以通過(guò)在其部分應(yīng)用程序中采用 SPARK 來(lái)獲得更高的保證。
MISRA C 中的規(guī)則代表了一項(xiàng)令人印象深刻的集體努力,旨在提高關(guān)鍵應(yīng)用程序中 C 代碼的可靠性,重點(diǎn)是避免容易出錯(cuò)的功能,而不是強(qiáng)制執(zhí)行特定的編程風(fēng)格。然而,從根本上說(shuō),MISRA C 仍然建立在一種基礎(chǔ)語(yǔ)言之上,而這種基礎(chǔ)語(yǔ)言的設(shè)計(jì)目的并不是為了支持大型高保證應(yīng)用程序。很難將可靠性、安全性和安全性改造成一門從一開始就沒(méi)有這些目標(biāo)的語(yǔ)言。
由于 C 仍將是 Linux 內(nèi)核等大型程序的基礎(chǔ)語(yǔ)言,我們可以預(yù)見(jiàn)兩種趨勢(shì)的共存,以更好地防止 C 程序中的錯(cuò)誤,其中 MISRA C 可以發(fā)揮作用,并用更安全的語(yǔ)言(如 Rust 和SPARK Ada 用于部分代碼。
審核編輯:郭婷
-
Linux
+關(guān)注
關(guān)注
88文章
11761瀏覽量
219057 -
代碼
+關(guān)注
關(guān)注
30文章
4968瀏覽量
73992 -
編譯器
+關(guān)注
關(guān)注
1文章
1672瀏覽量
51627
發(fā)布評(píng)論請(qǐng)先 登錄
AT32F011系列安全庫(kù)區(qū)的應(yīng)用
C語(yǔ)言安全編碼指南:MISRA C、CERT C、CWE 與 C Secure 標(biāo)準(zhǔn)對(duì)比與Perforce QAC應(yīng)用詳解
汽車網(wǎng)絡(luò)安全開發(fā)語(yǔ)言選型指南:C/C++/Rust/Java等主流語(yǔ)言對(duì)比+Perforce QAC/Klocwork工具支持
立宏安全#SM-602可編程安全控制器#LHS可編程安全控制器
請(qǐng)問(wèn)CW32L052C8T6這種安全性低功耗MCU的安全固件部分怎么實(shí)現(xiàn)?
單片機(jī)開發(fā)功能安全中編譯器
在物聯(lián)網(wǎng)設(shè)備面臨的多種安全威脅中,數(shù)據(jù)傳輸安全威脅和設(shè)備身份安全威脅有何本質(zhì)區(qū)別?
芯源半導(dǎo)體安全芯片技術(shù)原理
電機(jī)維修安全注意事項(xiàng)
邊聊安全 | 安全通訊中的失效率量化評(píng)估
無(wú)法將 XOM 設(shè)置為非安全區(qū)域,為什么?
存儲(chǔ)示波器在校準(zhǔn)過(guò)程中需要注意哪些安全問(wèn)題
Helix QAC 2025.1 重磅發(fā)布!MISRA C:2025? 100%覆蓋
MISRA C:2025新標(biāo)準(zhǔn)解析:新增規(guī)則、優(yōu)化點(diǎn)與靜態(tài)代碼分析工具支持(Perforce QAC、Klocwork)
MISRA C在安全和安全編程中的位置
評(píng)論