內(nèi)存標(biāo)簽擴展(Memory Tagging Extension,MTE)是Armv8.5-A中添加的新功能。
目前對計算機系統(tǒng)的攻擊,大部分是對內(nèi)存的攻擊。內(nèi)存安全問題又可以分為兩類:空間安全(spatial safety)和時間安全(temporal safety)。
當(dāng)試圖訪問安全區(qū)域以外的數(shù)據(jù),即違反了空間安全性,比如緩沖區(qū)溢出(Buffer Overflow)攻擊。緩沖區(qū)溢出是指在存在緩存溢出安全漏洞的計算機中,攻擊者可以用超出常規(guī)長度的字符數(shù)來填滿一個域,通常是內(nèi)存區(qū)地址。
緩存區(qū)溢出存在于各種電腦程序中,特別是廣泛存在于用C、C++等這些本身不提供內(nèi)存越界檢測功能的語言編寫的程序中,例如Debian中就存在5億行C/C++代碼。
當(dāng)試圖訪問已超出正常時間范圍的內(nèi)存資源時,即違反了時間安全性,比如釋放后再使用(Use After Free)攻擊。顧名思義,就是當(dāng)一個內(nèi)存塊被釋放之后再次被訪問。
攻擊程序可以先申請一塊內(nèi)存,然后釋放內(nèi)存,但是不清空該內(nèi)存指針,等待一段時間后再次通過指針對內(nèi)存進行訪問。如果恰好在訪問操作之前這塊內(nèi)存被分配給了其它的程序,那么攻擊程序可以通過內(nèi)存對此程序發(fā)起攻擊。
內(nèi)存攻擊不只以上提到的兩種。我不是安全專家,就不在這里啰嗦了。
可以通過軟件機制來檢測內(nèi)存訪問違例,但代價是運行效率低。
MTE提供一種硬件機制來檢測這兩類內(nèi)存違例的情況,這種機制類似于鎖和鑰匙的關(guān)系。在分配內(nèi)存的時候加上一把鎖,訪問的時候需要提供一把鑰匙,如果鑰匙和鎖不匹配,即阻止訪問,并報告錯誤。
具體來說,通過向物理內(nèi)存的每個16字節(jié)添加四-bit元數(shù)據(jù)(Metadata)來做內(nèi)存標(biāo)記;指針和虛擬地址被修改為包含鑰匙。16字節(jié)被定義為一個“標(biāo)簽顆粒(Tag Granule)”。為了在不需要較大指針的情況下實現(xiàn)鑰匙,Armv8-A架構(gòu)中使用“頂部字節(jié)忽略(Top Byte Ignore,TBI)”功能。
啟用TBI后,在做地址轉(zhuǎn)換時,虛擬地址的頂部字節(jié)會被忽略。這樣就可以使用頂部字節(jié)來存儲元數(shù)據(jù),實現(xiàn)內(nèi)存標(biāo)簽的鑰匙。當(dāng)前,僅使用頂部字節(jié)的4-bit。
來看一個例子,下圖上半部分,顯示的是緩沖區(qū)溢出情況。通過new()函數(shù)分配一個16-byte的內(nèi)存給ptr指針。當(dāng)程序通過ptr指針來訪問隨后的地址空間,會產(chǎn)生內(nèi)存違例,這是因為后面的內(nèi)存的鎖與ptr的鑰匙不相符。下圖下半部分,顯示的是UAF情況。當(dāng)內(nèi)存被再次分配時,產(chǎn)生了一個新鎖,如果攻擊程序用舊的指針去訪問,鑰匙和鎖不相符。
MTE支持標(biāo)簽的隨機產(chǎn)生,或基于種子的偽隨機產(chǎn)生。如果一個程序的執(zhí)行次數(shù)足夠,則至少其中一個程序檢測到違規(guī)的概率趨于100%。
或許你已經(jīng)注意到了一個細節(jié),那就是4-bit的元數(shù)據(jù)最多只能標(biāo)記16種不同的鎖。也就是說還有1/16的可能性,錯誤的鑰匙適配到了鎖。為了避免這類錯誤,需要軟件通過其它方式增加標(biāo)簽的不同可能性。
MTE增加了一種新的內(nèi)存類型,普通標(biāo)簽內(nèi)存(Normal Tagged Memory)。
地址中的標(biāo)簽和內(nèi)存中的標(biāo)簽之間的不匹配可以配置為導(dǎo)致同步異常(synchronous exception)或異步報告(asynchronous report)。
同步異常是精確的,因為可以精確地確定哪個加載或存儲指令導(dǎo)致了標(biāo)記不匹配。相反,異步報告是不精確的,因為它只能將不匹配隔離到特定的執(zhí)行線程。
MTE為Armv8-A體系結(jié)構(gòu)添加了三類指令:
- 適用于堆棧(stack)和堆(heap)標(biāo)記的標(biāo)簽操作指令
- IRG(insert random tag),此指令在第一個源寄存器的地址中插入一個隨機邏輯地址標(biāo)記,并將結(jié)果寫入目標(biāo)寄存器。IRG在硬件層面支持為一個寄存器中的地址插入隨機tag,這個tag隨后可以為其它指令使用。
- GMI(tag mask insert),將第一源寄存器中的標(biāo)記插入第二源寄存器中指定的排除集,將新的排除集寫入目標(biāo)寄存器。此指令用于操作與IRG指令一起使用的排除標(biāo)記集,適用于軟件為特殊目的使用特定標(biāo)記值,同時為正常分配保留隨機標(biāo)記行為的情況。
- LDG(load allocation tag),此指令從內(nèi)存地址加載分配標(biāo)記(allocation tag),從分配標(biāo)記生成邏輯地址標(biāo)記,并將其合并到目標(biāo)寄存器中。
- STG(store allocation tag),此指令存儲分配標(biāo)記到內(nèi)存
- STZG(store allocation tag, zeroing),此指令將分配標(biāo)記存儲到內(nèi)存,將相關(guān)數(shù)據(jù)位置歸零
- ST2G,此指令將分配標(biāo)記存儲到內(nèi)存的兩個標(biāo)記顆粒
- STZ2G,此指令將分配標(biāo)記存儲到內(nèi)存的兩個標(biāo)記顆粒,將相關(guān)數(shù)據(jù)位置歸零
- STGP(store allocation tag and pair of registers),此指令從兩個寄存器向內(nèi)存存儲一個分配標(biāo)記和兩個64位雙字
- 用于指針運算和堆棧標(biāo)記的指令
- ADDG(add with tag),此指令將由標(biāo)記顆粒縮放的立即數(shù)加到源寄存器中的地址,使用立即值修改地址的邏輯地址標(biāo)記,并將結(jié)果寫入目標(biāo)寄存器。
- SUBG(subtract with tag),此指令從源寄存器中的地址減去由標(biāo)記顆粒縮放的立即數(shù),使用立即數(shù)修改地址的邏輯地址標(biāo)記,并將結(jié)果寫入目標(biāo)寄存器。
- SUBP(subtract pointer),此指令從第一源寄存器中保存的56位地址減去第二源寄存器中保留的56位的地址,符號擴展結(jié)果到64位,并將結(jié)果寫入目標(biāo)寄存器。
- 用于系統(tǒng)的指令
- LDGM(load tag multiple),此指令讀取N個分配標(biāo)記的自然對齊塊
- STGM(store tag multiple),此指令存儲N個分配標(biāo)記的自然對齊塊
- STZGM(store tag and zero multiple),此指令存儲N個分配標(biāo)記的自然對齊塊,并將零存儲到相關(guān)數(shù)據(jù)位置
為了在后續(xù)產(chǎn)品種加入MTE,ARM將開發(fā)新版本的CHI協(xié)議,以支持MTE的傳輸和一致性要求。
為了支持MTE,還需要對軟件進行部署。ARM正在進行相關(guān)的工作。
MTE無需更改程序源代碼。然而,MTE必然會導(dǎo)致開銷,因為標(biāo)簽必須從內(nèi)存系統(tǒng)中提取并存儲到內(nèi)存系統(tǒng)中。這種開銷與內(nèi)存分配的大小和生命周期以及標(biāo)記和數(shù)據(jù)是一起操作還是單獨操作有關(guān)。開銷可以通過以下方式最小化:
- 同時寫入標(biāo)簽和初始化內(nèi)存
- 避免過度分配從未寫入數(shù)據(jù)的地址空間
- 避免過度的釋放和重新分配
- 避免在堆棧上分配大塊固定大小內(nèi)存
-
計算機
+關(guān)注
關(guān)注
19文章
7643瀏覽量
90476 -
C++
+關(guān)注
關(guān)注
22文章
2118瀏覽量
74964 -
ARMv8
+關(guān)注
關(guān)注
1文章
35瀏覽量
14438
發(fā)布評論請先 登錄
Armv9引入的MTE已成內(nèi)存安全的新防線
Armv8.5-A中添加的新功能—內(nèi)存標(biāo)簽擴展MTE
手機自帶內(nèi)存和擴展內(nèi)存有什么區(qū)別 哪個更好
如何給手機擴展內(nèi)存
最新消息:華為推出全新的內(nèi)存擴展技術(shù)
EE-32:語言擴展:內(nèi)存存儲類型、ASM和內(nèi)聯(lián)構(gòu)造

基于51單片機6264擴展內(nèi)存仿真設(shè)計(proteus仿真+程序)

瀾起科技發(fā)布全球首款CXL?內(nèi)存擴展控制器芯片
UM1800_STM32Nucleo的動態(tài)NFC、RFID標(biāo)簽芯片擴展板入門

評論