這是由四部分組成的系列文章的第四部分,介紹了獨(dú)特的產(chǎn)品 MPU-Plus? 以及使用 Cortex-M 內(nèi)存保護(hù)單元 (MPU) 實(shí)現(xiàn)改進(jìn)的微控制器單元 (MCU) 安全性的方法。第 3 部分介紹了分區(qū)問題,包括堆使用、函數(shù)調(diào)用 API、中斷、父任務(wù)和子任務(wù)以及任務(wù)本地存儲(chǔ)。第 2 部分介紹了分區(qū)、安全啟動(dòng)、MPU 控制和系統(tǒng)調(diào)用。 第 1 部分介紹了一些介紹性概念:MMU 與 MPU、對(duì)安全性的需求不斷增加、保護(hù)目標(biāo)、MPU Plus 快照、Cortex-v7M 和 v8M 以及 MPU 操作。
動(dòng)態(tài)區(qū)域
如前所述,創(chuàng)建靜態(tài)區(qū)域是一個(gè)耗時(shí)、繁瑣且容易出錯(cuò)的過程。下面討論的動(dòng)態(tài)數(shù)據(jù)區(qū)域有助于減輕一些負(fù)擔(dān)。
動(dòng)態(tài)數(shù)據(jù)區(qū)域
以下函數(shù)允許在初始化期間或從 ptask 動(dòng)態(tài)創(chuàng)建數(shù)據(jù)區(qū)域:
u8* mp_RegionGetHeapR(rp, sz, sn, attr, name, u32 hn);
u8* mp_RegionGetPoolR(rp, pool, sn, attr, 名稱);
布爾mp_RegionMakeR(rp, bp, sz, sn, attr, name);
其中 rp 是指向所創(chuàng)建區(qū)域的指針,sz 是區(qū)域大小,sn 是插槽號(hào),attr 是屬性,名稱是區(qū)域的可選名稱,hn 是堆編號(hào),池是塊池句柄,bp 是塊指針。上述內(nèi)容可用于分別從堆、塊池或靜態(tài)塊(例如stat_blk[100])創(chuàng)建數(shù)據(jù)區(qū)域。
通常 rp 指向動(dòng)態(tài)保護(hù)區(qū)域數(shù)組 dpr[n] 中的條目。然后,按如下方式設(shè)置動(dòng)態(tài)區(qū)域的 MPA 模板槽:
mpa_tmplt_t2a=MP_DYN_RGN;
其中 MP_DYN_RGN() 加載 dpr[n] 的地址,并在模板槽中設(shè)置動(dòng)態(tài)區(qū)域標(biāo)志。
這些函數(shù)通常應(yīng)在任務(wù)開始運(yùn)行之前在系統(tǒng)初始化期間調(diào)用。但是,它們也可以由 ptask 調(diào)用,這些 ptask 正在創(chuàng)建和初始化其他任務(wù)。
動(dòng)態(tài)數(shù)據(jù)區(qū)域可用于存儲(chǔ)靜態(tài)數(shù)組和結(jié)構(gòu)的混合,并且可以在任務(wù)之間共享它們。盡管它們不能用于全局變量,但它們確實(shí)節(jié)省了在代碼中定義節(jié)、在鏈接器命令文件中定義塊以及在模板中定義靜態(tài)區(qū)域的復(fù)雜性。因此,它們更簡單,更不容易出錯(cuò)。鑒于 sz 很可能是大小 () 的總和,它們?cè)陂_發(fā)過程中也可能更靈活。
受保護(hù)的數(shù)據(jù)塊
以下受保護(hù)的塊函數(shù)允許從 utask 或 ptask 創(chuàng)建受保護(hù)的數(shù)據(jù)塊,并在運(yùn)行時(shí)釋放它們:
u8* smx_PBlockGetHeap(sz, sn, attr, name, hn);
u8* smx_PBlockGetPool(pool, sn, attr, name);
BOOLEAN smx_PBlockMake(bp, sz, sn, attr, name);
BOOLEAN smx_PBlockRelHeap(bp, sn, hn);
BOOLEAN smx_PBlockRelPool(bp, sn, pool, clrsz);
其中參數(shù)與動(dòng)態(tài)區(qū)域的參數(shù)相同,不同之處在于對(duì)于發(fā)布函數(shù),bp 是其中一個(gè) Get 函數(shù)返回的塊指針,clrsz 指定在塊的第一個(gè)字中的可用塊鏈接之后要清除多少字節(jié)。基本上,塊是從堆或池中獲取的,或者由靜態(tài)塊制成的。為它創(chuàng)建一個(gè)區(qū)域,并將其加載到當(dāng)前任務(wù)的 MPU[sn] 和 MPA[sn] 中。堆可以是任何堆,包括主堆。這是安全的,因?yàn)槿绻?a href="http://www.nxhydt.com/v/tag/10353/" target="_blank">黑客滲透到任務(wù)中,MPU 會(huì)阻止他訪問受保護(hù)塊之外的堆內(nèi)存。
動(dòng)態(tài)分配的塊可用于緩沖區(qū)、工作區(qū)、消息(見下文)或結(jié)構(gòu)。如果任務(wù)的編寫使得其所有靜態(tài)變量都在結(jié)構(gòu)中,例如:
u8* VP;
vp-》var1 = vp-》var2 + vp-》var3;
然后可以使用動(dòng)態(tài)塊來存儲(chǔ)其靜態(tài)變量。在上面,vp 是塊Get()函數(shù)返回的塊指針。(請(qǐng)注意,vp 是一個(gè) auto 變量,因此存儲(chǔ)在任務(wù)堆棧中,而不是結(jié)構(gòu)中)。如果一個(gè)函數(shù)不是以這種方式編寫的,那么轉(zhuǎn)換它并不困難 - 只需在每個(gè)靜態(tài)變量引用之前插入“vp-》”,定義一個(gè)VP結(jié)構(gòu),將變量名稱作為字段,并將vp定義為指向VP的指針。
受保護(hù)的數(shù)據(jù)塊和動(dòng)態(tài)數(shù)據(jù)區(qū)域之間的區(qū)別在于,受保護(hù)的數(shù)據(jù)塊可以在任務(wù)運(yùn)行時(shí)獲取,而動(dòng)態(tài)數(shù)據(jù)區(qū)域是在初始化期間創(chuàng)建的,并且指向它的指針加載到任務(wù)的模板中。受保護(hù)的數(shù)據(jù)塊對(duì)于用于創(chuàng)建臨時(shí)緩沖區(qū)和受保護(hù)消息的 utask 特別有用,如下所述。
使用動(dòng)態(tài)區(qū)域
使用動(dòng)態(tài)數(shù)據(jù)區(qū)域、受保護(hù)的數(shù)據(jù)塊或 TLS 替換task_data靜態(tài)區(qū)域需要將所有任務(wù)全局變量重新定義為一個(gè)或多個(gè)結(jié)構(gòu)中的字段。如果結(jié)構(gòu)名稱非常短,這不會(huì)明顯使代碼復(fù)雜化。例如,下面是來自電子堆的一些代碼:
》EH_OK;
bsmap = hvp[hn]-》地圖;
csbin = hvp[hn]-》
為了支持多個(gè)堆,有必要將離散全局變量更改為一組結(jié)構(gòu) hvp[hn]。在本例中,hvp[hn]-》粘貼到代碼中每個(gè)全局變量名稱的開頭。Cortex-M 架構(gòu)允許以與離散全局變量一樣快或更快的速度訪問結(jié)構(gòu) – 函數(shù)中的一條 LDM 指令加載結(jié)構(gòu)基址,然后通過常量偏移訪問字段。編譯器可能無法對(duì)函數(shù)使用的所有離散全局變量執(zhí)行此操作,因此訪問它們的速度可能會(huì)較慢。使用結(jié)構(gòu)還允許將一起使用的字段組合在一起,如果處理器具有指令緩存,則可以提高性能。通過使用 sizeof() 來確定指針偏移量,可以自動(dòng)處理多個(gè)結(jié)構(gòu)和數(shù)組。
受保護(hù)的郵件
smx 消息由鏈接到數(shù)據(jù)塊的消息控制塊 (MCB) 組成。smx_MsgMake() 函數(shù)可用于將受保護(hù)的數(shù)據(jù)塊轉(zhuǎn)換為受保護(hù)的郵件,當(dāng)前任務(wù)將成為郵件所有者。消息發(fā)送到消息交換,并從消息交換接收。在消息交換時(shí),消息的 MCB 鏈接到交換的控制塊,進(jìn)入等待消息隊(duì)列。
圖 11 說明了在任務(wù)之間傳輸受保護(hù)的郵件。任務(wù) A 顯示為綠色,任務(wù) B 顯示為藍(lán)色。黃色表示 p 代碼和 pdata,它們受任一任務(wù)的影響。如圖所示,TaskA 在槽 sn 中獲取一個(gè) pdata 塊,將其制作成一條消息,加載它,然后將其發(fā)送到 Xchg。作為發(fā)送操作的一部分,MPU 和任務(wù) A 的 MPA 中的插槽 sn 將被清除。請(qǐng)注意,其他消息正在 Xchg 等待,而 MCBi 位于消息隊(duì)列的頂部。任務(wù) B 在插槽 sx 中接收它。請(qǐng)注意,rbar 和 rasr 是從 MCBi 獲取的,用于在插槽 sx 中為消息的 pdata 塊創(chuàng)建區(qū)域。TaskB 驗(yàn)證消息,該消息與應(yīng)用程序相關(guān),可能包括對(duì)數(shù)據(jù)執(zhí)行范圍和一致性檢查。然后,它處理 pdata,取消生成消息,將插槽 sx 中的 pdata 塊釋放回其堆或池,并清除 MPU 和 TaskB 的 MPA 中的插槽 sx。
smx 中添加了兩個(gè)受保護(hù)的郵件函數(shù):
MCB_PTR smx_PMsgReceive(xp, bpp, sn, 超時(shí));
布爾smx_PMsgSend(mp, xp, sn, pri, rp);
其中 xp 是交換指針,bpp 是指向消息塊指針的指針,sn 是 MPU/MPA 插槽號(hào),超時(shí)以刻度為單位,mp 是消息指針,pri 是消息優(yōu)先級(jí),rp 是回復(fù)指針(例如,發(fā)送到交換發(fā)送回復(fù)消息。)
如圖 11 所示,當(dāng)發(fā)送受保護(hù)的消息時(shí),MPU 和當(dāng)前任務(wù)的 MPA 中的插槽 sn 將被清除。因此,即使發(fā)送任務(wù)保留了指向消息塊(例如 bpp)的指針,它也無法訪問消息塊。這挫敗了在另一個(gè)分區(qū)中的接收任務(wù)驗(yàn)證消息后更改消息的黑客技術(shù)。它還會(huì)阻止在另一個(gè)分區(qū)中的接收任務(wù)更新消息后讀取消息。
在交換時(shí),消息塊區(qū)域信息存儲(chǔ)在消息的 MCB 中,并且交換是消息的所有者。當(dāng)接收任務(wù)接收到消息時(shí),其消息塊區(qū)域信息被加載到 MPU 和接收方 MPA 的指定槽 sx 中,接收任務(wù)成為消息所有者。(sx 不必與發(fā)送任務(wù)使用的插槽相同。
現(xiàn)在,接收任務(wù)可以讀取和修改消息,并可能將其發(fā)送到另一個(gè)交換。因此,可以創(chuàng)建一條消息,加載數(shù)據(jù),傳遞給任務(wù)以檢查數(shù)據(jù)并對(duì)其進(jìn)行加密,然后傳遞給第三個(gè)任務(wù)以通過網(wǎng)絡(luò)發(fā)送它。請(qǐng)注意,發(fā)送任務(wù)和接收任務(wù)之間存在完全隔離。當(dāng)然,發(fā)件人可以發(fā)送某種破壞性消息。因此,接收方必須在接受消息之前執(zhí)行驗(yàn)證。此安全級(jí)別是特定于應(yīng)用程序的。
分區(qū)門戶
如 第 3 部分 所述,分區(qū)入口支持將客戶機(jī)分區(qū)與服務(wù)器分區(qū)隔離,并且是實(shí)現(xiàn) 100% 分區(qū)隔離所必需的,這對(duì)于實(shí)現(xiàn)強(qiáng)安全性至關(guān)重要。它們建立在上述受 smx 保護(hù)的郵件之上。受保護(hù)的郵件滿足 Arm PSA 安全 IPC 要求(請(qǐng)參閱第 1 部分中的參考文獻(xiàn) 3),而無需復(fù)制郵件。因此,引入門戶與普通函數(shù)調(diào)用 API 可能不會(huì)明顯降低性能。
如圖 12 所示,分區(qū)入口由標(biāo)記為 XI 和 XO 的交換組成 — 每個(gè)方向一個(gè)。添加到客戶機(jī)分區(qū)的代碼(由虛線右側(cè)的區(qū)域表示)將函數(shù)調(diào)用及其參數(shù)轉(zhuǎn)換為發(fā)送到 XI 交換的消息。然后,客戶端任務(wù)在 XO 交換處等待回復(fù)消息。
在添加到服務(wù)器端的代碼中(由虛線左側(cè)的區(qū)域表示)中的服務(wù)器任務(wù)正在 XI 交換處等待消息。當(dāng)它收到消息時(shí),它會(huì)使用消息中的參數(shù)將其轉(zhuǎn)換為函數(shù)調(diào)用。然后,它將來自函數(shù)調(diào)用的返回信息放入發(fā)送到 XO 交換的消息中。客戶端任務(wù)從 XO 交換接收消息,并將信息返回給客戶端分區(qū)中的調(diào)用方。
顯然,要將分區(qū)之間的函數(shù)調(diào)用接口轉(zhuǎn)換為分區(qū)門戶,需要做很多工作。但是,結(jié)果是強(qiáng)分區(qū)隔離。當(dāng)然,這會(huì)降低性能。數(shù)據(jù)緩沖區(qū)在消息中傳遞。如果正在修改現(xiàn)有代碼,則可能需要將數(shù)據(jù)從緩沖區(qū)復(fù)制到消息,反之亦然。如果要?jiǎng)?chuàng)建新代碼,則可以將其設(shè)計(jì)為在無復(fù)制模式下處理消息。在后一種情況下,性能影響可能很小。
請(qǐng)注意,數(shù)據(jù)復(fù)制問題也存在于基于 MMU 的大型系統(tǒng)中。實(shí)際上,在這種情況下,由于虛擬地址空間,不存在無復(fù)制解決方案。因此,在基于 MPU 的系統(tǒng)中,通過入口進(jìn)行的分區(qū)間通信可能比基于 MMU 的系統(tǒng)中的進(jìn)程間通信更有效。這有利于較小的分區(qū),每個(gè)分區(qū)執(zhí)行較少的工作,因此系統(tǒng)安全性可能更好。較小的分區(qū)也使冗余路徑更實(shí)用 - 例如,兩個(gè)獨(dú)立的路徑將可疑活動(dòng)報(bào)告回總部。
調(diào)試支持
啟用安全功能時(shí),調(diào)試代碼更具挑戰(zhàn)性。因此,SecureSMX 允許在早期代碼開發(fā)和調(diào)試期間覆蓋大多數(shù)安全功能,以幫助加快這些階段。可以在后期調(diào)試期間重新啟用安全功能,通過檢測堆棧和緩沖區(qū)溢出以及其他問題,它們實(shí)際上會(huì)變得很有幫助。此外,建議在開發(fā)走得太遠(yuǎn)之前開始解決安全問題。
smx軟件?包括許多與安全相關(guān)的功能,以幫助調(diào)試基于MPU Plus的軟件。它顯示當(dāng)前 MPU 和所有任務(wù) MPA,以及命名區(qū)域。圖形化的內(nèi)存映射概述在內(nèi)存條中顯示 MPU 區(qū)域。將顯示開始地址和結(jié)束地址以及排除的子區(qū)域。在所有顯示器中,都會(huì)標(biāo)記對(duì)齊和重疊等錯(cuò)誤。有關(guān)詳細(xì)信息,請(qǐng)參閱:
smxAware用戶指南,由馬蒂·科克倫和大衛(wèi)·摩爾,微數(shù)碼公司。
結(jié)論
軟件工程已經(jīng)失去了它的天真 - 我們現(xiàn)在正在為一個(gè)充滿敵意的世界設(shè)計(jì)。不可能實(shí)現(xiàn)完美的安全性,但它可以非常好。毫無疑問,一個(gè)堅(jiān)定的黑客會(huì)發(fā)現(xiàn)一些弱點(diǎn),即使是你能設(shè)計(jì)出的最好的安全性。因此,有必要分析所有代碼與可能的威脅。
在某些情況下,代碼體的設(shè)計(jì)和實(shí)現(xiàn)可能非常糟糕,因此非常脆弱,以至于重新設(shè)計(jì)它是一個(gè)毫無希望的命題。在這種情況下,使用本文中介紹的方法將代碼保持原樣并將其放入完全隔離的 umode 分區(qū)中可能更具成本效益。然后,有必要設(shè)計(jì)一個(gè)策略來處理不可避免的闖入,并實(shí)現(xiàn)必要的代碼來處理它。在此過程中,可能會(huì)發(fā)現(xiàn)一些潛在的錯(cuò)誤。
如果升級(jí)舊代碼以提高現(xiàn)有產(chǎn)品的安全性,或者使用舊代碼開發(fā)新產(chǎn)品,則主要工作通常是重構(gòu)舊代碼。所需的重新編碼量可能很小,具體取決于代碼開始時(shí)的結(jié)構(gòu)。當(dāng)然,新代碼應(yīng)該從一開始就為安全而設(shè)計(jì)。
安全性為產(chǎn)品開發(fā)增加了另一個(gè)維度。不僅要考慮如何實(shí)現(xiàn)功能,還要考慮黑客如何訪問該功能以造成損害或竊取私人數(shù)據(jù)。MMF在調(diào)試過程中很煩人,但它們證明了硬件安全機(jī)制確實(shí)有效!MPU-Plus的目標(biāo)是提供一條路徑,在不造成過度痛苦的情況下實(shí)現(xiàn)良好的安全性。
審核編輯:郭婷
-
微控制器
+關(guān)注
關(guān)注
48文章
7487瀏覽量
151042 -
mcu
+關(guān)注
關(guān)注
146文章
16984瀏覽量
350293 -
MPU
+關(guān)注
關(guān)注
0文章
346瀏覽量
48735
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論