焦芃源,李 涵,李翔宇,殷樹娟
(1.北京信息科技大學 理學院,北京 100192;2.清華大學 微電子學研究所,北京 100084)
為保證嵌入式設備中存儲的個人隱私信息不被竊取,采用一個安全的處理器至關重要。特權模式和物理內存保護是安全嵌入式處理器的必備特性。ARM Cortex- M3架構處理器支持兩種特權模式對程序訪問存儲器的操作做出限制[1]。x86架構處理器劃分為4個特權模式,稱之為保護環(huán)[2]。這種分級隔離執(zhí)行[3]的策略是許多不同指令集架構處理器都采用的安全技術。RISC-V是由加州伯克利分校推出的一種精簡指令集架構[4]。RISC-V指令集架構也采用特權模式來保障處理器的安全。此外,安全的內存訪問權限管理是保障處理器安全的前提。RISC-V指令集架構提供了物理內存保護單元(physical memory protection unit,PMP)[5],通過對內存訪問進行控制來保證內存的安全。
已有許多學者對不同架構的處理器進行過安全性測試。李錫星等[6]針對x86架構處理器中的“幽靈”、“熔斷”等漏洞,提出了基于漏洞特征提取的處理器漏洞檢測技術。袁野[7]基于GlobalPlatform標準,對ARM架構的Trustzone硬件隔離機制與內存訪問控制進行了安全性測試。張錚等[8]采用黑盒測試等方法對一款異構處理器的模式切換機制等功能進行了測試。但是目前針對RISC-V特權模式和物理內存防護機制的測試較少。本文基于一個RISC-V架構的32位處理器,針對RISC-V架構中的特權模式切換與物理內存訪問控制這兩個處理器安全特性設計了一套測試方案,并進行了測試。
RISC-V指令集架構有3種特權模式:機器模式(machine mode,M-Mode)、用戶模式(user mode,U-Mode)和監(jiān)管者模式(supervisor mode,S-Mode)[9]。其中M-Mode是所有RISC-V處理器必須具備的特權模式,也是處理器上電后的默認模式。M-Mode對整個系統(tǒng)資源具有最高的訪問權限。但在運行不可信代碼時,僅具有M-Mode的處理器不能保護系統(tǒng)免受不可信代碼的侵害,故處理器應增加U-Mode和S-Mode特權模式和PMP來限制不可信代碼的行為。U-Mode一般運行不可信的用戶代碼,其權限最低。S-Mode的權限介于M-Mode和U-Mode之間。PMP是一個為物理內存空間指定讀寫和代碼執(zhí)行權限的單元,在一些資源有限的嵌入式系統(tǒng)中可以以較低的開銷實現(xiàn)內存訪問控制。PMP最多支持16個條目對內存空間進行劃分,每個條目定義一個需要限制訪問權限的內存地址區(qū)間,每個條目由一個配置寄存器和地址寄存器來描述。配置寄存器具有鎖定(L)、地址匹配模式(A)以及代碼執(zhí)行(X)、讀(R)和寫(W)字段,結合地址寄存器對內存空間的訪問進行控制。特權模式和PMP可對處理器的運行提供安全保護,故應對這些特性的有效性進行測試。
本文對一款32位RISC-V安全處理器的3種特權模式和PMP的內存保護機制進行測試。被測處理器是一個簡單片上系統(tǒng)(system on chip,SoC)。該SoC包含一個RISC-V 32位處理器核心、512 KB的指令存儲器和256 KB的數(shù)據(jù)存儲器,并集成了JTAG (joint test action group)、UART(universal asynchronous receiver/transmitter)等外圍設備。外圍設備中的JTAG和UART與PC機通過USB口相連,用作測試程序的下載、調試、運行以及運行結果的輸出。測試程序源代碼采用C和RISC-V匯編語言混合編寫并使用RISC-V交叉編譯工具鏈對程序進行編譯、匯編與鏈接生成可執(zhí)行程序。調試和運行的結果通過串口終端打印進行顯示。
2.2.1 處理器特權模式切換測試
低特權模式的不可信代碼執(zhí)行越權操作或者進行系統(tǒng)調用時應觸發(fā)異常,默認交由最高特權模式M-Mode的異常例程進行處理。在存在異常委托的情況下,低特權模式觸發(fā)的異常也可以委托給S-Mode的異常例程處理。因此應測試處理器在U-Mode下執(zhí)行了越權操作或者進行系統(tǒng)調用后能否觸發(fā)M-Mode的異常;在U-Mode系統(tǒng)調用委托給S-Mode的情況下,U-Mode的系統(tǒng)調用是否能夠通過異常委托的方式進入到S-Mode;在S-Mode下執(zhí)行越權操作或進行系統(tǒng)調用后能否觸發(fā)M-Mode異常。
RISC-V處理器中具有一些特殊指令和控制狀態(tài)寄存器(control status registers,CSR)用來控制和指示處理器硬件的狀態(tài)。具體地,mret是M-Mode異常退出指令,mstatus CSR是M-Mode下指示處理器狀態(tài)的寄存器。mstatus CSR的MPP字段用于切換特權模式時保存切換前的特權模式,其中MPP字段00代表U-Mode,01代表S-Mode,11代表M-Mode。將mstatus CSR的MPP字段寫入對應的值,執(zhí)行mret指令后,處理器應根據(jù)mstatus的MPP字段恢復特權模式,來達到特權模式的切換。若寫入01,就切換到S-Mode,若寫入00,就切換到U-Mode。
S-Mode向其他模式切換也可采用類似的方法。sret是S-Mode異常退出指令。sstatus CSR是S-Mode下指示處理器狀態(tài)的寄存器,與mstatus CSR類似,sstatus CSR的SPP字段中0代表U-Mode,1代表S-Mode。故通過寫0到sstatus CSR的SPP字段,然后執(zhí)行sret異常退出指令可切換到U-Mode。S-Mode到M-Mode的切換通過調用ecall指令觸發(fā)環(huán)境調用異常來實現(xiàn)。
U-Mode下切換到M-Mode可以直接調用ecall指令,從而進入到M-Mode的異常例程。RISC-V中默認任何特權模式下發(fā)生的異常均會交由M-Mode來處理。若要從U-Mode切換到S-Mode,也可以使用ecall指令,但需要在U-Mode下執(zhí)行ecall指令觸發(fā)用戶環(huán)境調用異常之前將該異常委托給S-Mode來處理。medeleg CSR是異常委托寄存器。在M-Mode下應將medeleg CSR寄存器中對應用戶環(huán)境調用異常的字段置1實現(xiàn)用戶環(huán)境調用異常的委托。然后需要在ecall指令的異常例程代碼中保存通用寄存器上下文,并將sepc CSR的值自增4,這么做是因為sepc CSR保存的是異常發(fā)生時指令的地址,退出異常時處理器會根據(jù)sepc CSR指定地址的指令執(zhí)行從而重新觸發(fā)異常。若要程序繼續(xù)執(zhí)行下去,應將sepc CSR指向發(fā)生異常的指令的下一條指令。要使得處理器能成功從U-Mode跳入S-Mode異常例程,還需要將該異常例程的入口地址存入stvec CSR。
為確定特權模式切換是否成功,必須要對處理器當前所處的特權模式進行檢測。但是RISC-V處理器中不存在反映當前處理器所處特權模式的寄存器,因此只能采用間接的方法測試。本文設計了執(zhí)行每種Mode下合法指令和非法指令的特權模式檢測方法。mstatus CSR是M-Mode下指示處理器狀態(tài)的寄存器。例如由M-Mode切換到S-Mode后,讀mstatus CSR操作非法而讀sstatus CSR合法,而由M-Mode切換到U-Mode后,讀mstatus和sstatus操作均非法。非法指令會觸發(fā)非法指令異常,通過串口打印輸出mcause CSR、mepc CSR的值可以觀察發(fā)生的異常類型、異常發(fā)生時指令的地址,該地址可以通過objdump工具對可執(zhí)行程序進行反匯編來確定發(fā)生異常指令的地址是否為待測非法指令的地址。
特權模式切換的整體測試流程如圖1所示,一共有3個測試分支。首先處理器上電默認進入M-Mode。PMP所有條目字段默認為0。通過對PMP條目的地址寄存器和配置寄存器進行初始化配置,將處理器的指令存儲和數(shù)據(jù)存儲劃分為若干區(qū)間,默認所有PMP條目均不鎖定且具有讀寫和代碼執(zhí)行權限。接下來完成特權模式切換的測試。特權模式切換采用M → U→ M→ S→ U→ S→ M的順序,這樣的轉換次序既將6種可能的模式切換方式都包括在內,又在程序的實現(xiàn)上比較容易。其中U→ M和U→ S都是在U-Mode下執(zhí)行了ecall指令,觸發(fā)環(huán)境調用異常后卻分別切換到不同的特權模式,從而測試了異常委托的有效性。此外,通過讀mstatus CSR和sstatus CSR是否觸發(fā)非法指令異常也間接測試了模式切換的正確性。
圖1 處理器特權模式切換測試方案流程
2.2.2 PMP內存訪問控制測試
PMP配置和地址寄存器的不同設定對運行在3種特權模式下的代碼有著不同的內存訪問限制。對內存進行非法的讀、寫與代碼執(zhí)行操作均應觸發(fā)高特權模式的異常并交由高特權模式進行處理。因此應分別測試在M-Mode下,對鎖定的PMP條目的地址與配置寄存器的修改能否被禁止,對鎖定的PMP條目內存地址空間的讀寫與代碼執(zhí)行控制是否有效。此外,mstatus CSR的MPRV字段若置1,M-Mode下的內存讀寫操作也應符合PMP權限控制規(guī)則。故應測試mstatus CSR的MPRV字段置1時對未鎖定但無讀寫權限的PMP條目內存地址空間的讀寫操作能否被禁止。另外還應測試在S-Mode和U-Mode下對PMP條目內存地址空間進行讀寫與代碼執(zhí)行操作的控制是否有效。
為測試內存的讀、寫權限控制是否有效,可以分別將PMP條目的配置寄存器的R、W字段置0,然后讀、寫該條目地址寄存器規(guī)定范圍內的地址,并觀察是否觸發(fā)Load Access Fault或Store Access Fault異常。為了確定觸發(fā)的異常類型,可以在異常例程中輸出mcause CSR的值,然后通過串口打印這些寄存器的值來檢驗。對內存代碼執(zhí)行權限控制是否有效的測試,我們采用子過程調用的方法,將一段待測代碼封裝為一個子過程。為了使得測試程序對這個子過程不具有代碼執(zhí)行權限,需要確定該子過程在內存中所處的地址范圍。具體地,可以在測試程序中定義一個子過程并編寫測試程序其他部分,再將測試程序編譯匯編鏈接成可執(zhí)行文件后使用objdump將可執(zhí)行文件進行反匯編來確定子過程所處的地址段。之所以不采用地址跳轉的方式,是因為測試程序的改動可能會改變待測子過程的地址,不便于PMP地址寄存器的配置。在PMP鎖定功能的測試中,可通過將PMP條目的配置寄存器鎖定位寫入1來鎖定條目。由于PMP條目鎖定后對該條目的配置與地址寄存器的修改不會觸發(fā)異常,可通過分別在鎖定條目前、后修改寄存器值的對比來確定鎖定操作是否有效。
PMP內存訪問控制測試方案的流程如圖2所示,共分為5個測試分支。被測處理器中配置有8個PMP條目。因為代碼執(zhí)行權限的測試需要有指令執(zhí)行,故PMP管理的內存應包括數(shù)據(jù)存儲空間和指令存儲空間。在被測處理器中指令和數(shù)據(jù)分別存儲在兩個存儲器中。為了全面測試數(shù)據(jù)和指令的訪問控制,在處理器上電后PMP條目初始的配置是8個PMP條目的地址寄存器中前4個地址區(qū)間位于指令存儲器中,接下來的3個地址區(qū)間位于數(shù)據(jù)存儲器中。因為U-Mode和S-Mode默認對不在PMP條目中的地址不具有訪問權限,為了能夠在U-Mode和S-Mode下通過串口輸出信息,將最后1個PMP條目的地址寄存器的值設置為UART外設映射在內存中的地址。8個PMP配置寄存器LXWR字段的初始值為0111,即不鎖定且可讀可寫可執(zhí)行。
圖2 PMP內存訪問控制測試方案流程
在測試1中,可以鎖定一個PMP條目進行測試。首先在條目未鎖定時串口打印該條目的配置和地址寄存器的值,然后修改、鎖定并打印出它們的值,鎖定后再修改該條目的地址和配置寄存器的值,并打印PMP條目寄存器的值檢驗修改是否生效。
在測試2中,PMP初始設置與測試1相同。首先可以修改一個PMP條目的配置寄存器只有寫或只有讀權限并鎖定,然后對該條目進行讀和寫操作觀察串口打印的異常信息。在代碼執(zhí)行權限的測試中,我們將PMP條目的地址寄存器配置成被調用子過程的地址區(qū)間。由于PMP規(guī)則要求條目的地址區(qū)間4字節(jié)對齊,可以通過在測試程序中子過程的前后加上4字節(jié)對齊偽指令來實現(xiàn)。測試程序修改PMP條目的配置寄存器不具有代碼執(zhí)行權限并鎖定,然后調用該子過程觀察串口打印的異常信息。
在測試3中,僅需再做內存讀寫操作之前修改mstatus CSR 的MPRV字段為1即可,內存的讀寫測試可以復用測試2的代碼。
在測試4和測試5中,分別令程序進入U-Mode或者S-Mode,然后對不匹配任何PMP條目的地址進行讀和寫操作,觀察串口打印的異常信息。而對匹配了PMP條目的地址的讀、寫與代碼執(zhí)行的操作可以復用測試2中內存訪問測試的代碼。
2.3.1 特權模式切換測試結果與分析
特權模式切換的測試根據(jù)圖1的流程分為3個測試項,測試結果輸出如下。
1)處理器能否切換至U-Mode
輸出結果:
Enter Illegal Instruction Exception Handler:
MCAUSE:0x2
MEPC:0x80000322
結果分析:程序中讀sstatus CSR操作后輸出mcause CSR的值為0x2,最低字節(jié)表明觸發(fā)了Illegal Instruction Fault 異常(異常編號2),對應的第[29∶28]位為二進制的00,指示觸發(fā)異常前已切換到U-Mode。
2)處理器能否切換至S-Mode
輸出結果:
Enter Illegal Instruction Exception Handler:
MCAUSE:0x18000002
MEPC:0x80000380
結果分析:程序中讀sstatus CSR操作沒有觸發(fā)異常,讀mstatus CSR后mcause CSR的值輸出為0x18000002,最低字節(jié)表明觸發(fā)了Illegal Instruction Fault 異常(異常編號2),第[29∶28]位為二進制的01,指示觸發(fā)異常前已切換到S-Mode。
3)M→U→M→S→U→S→M不觸發(fā)非法指令異常的切換流程
輸出結果:
Enter U-mode Ecall Handler:
Exit U-mode Ecall Handler:
Enter Delegate S-mode Handler For U-mode ecall:
Exit Delegate S-mode Handler For U-mode ecall:
Enter S-mode Ecall Handler:
Exit S-mode Ecall Handler.
結果分析:從測試結果看出M-Mode切換到U-Mode后,從U-Mode下執(zhí)行ecall指令進入到M-Mode的用戶環(huán)境調用異常處理程序。退出異常后修改medeleg CSR將U-Mode的環(huán)境調用異常委托給S-Mode,該修改過程沒有觸發(fā)異常,表明處理器處于M-Mode。并且之后通過M→S→U模式切換后執(zhí)行ecall指令,進入到委托給S-Mode的用戶環(huán)境調用異常處理程序。退出異常處理程序后處理器處于S-Mode,再執(zhí)行ecall指令,進入到監(jiān)管者環(huán)境調用異常處理程序中。退出異常后回到M-Mode,程序結束。結果表明6種模式切換方式均可實現(xiàn)。
2.3.2 PMP內存訪問控制測試結果與分析
PMP內存訪問控制的測試根據(jù)圖2的流程分為5個測試項,測試結果輸出如下。
1)PMP條目鎖定后修改條目的配置和地址寄存器
輸出結果:
PMPADDR:0x24004fff PMPCFG:0x1f
PMPADDR:0x24005fff PMPCFG:0x9f
PMPADDR:0x24005fff PMPCFG:0x9f
結果分析:PMP條目寄存器值的輸出結果第一行為初始化值打印,而第二行為修改未鎖定條目的寄存器的值且修改成功,第三行為對條目鎖定后對地址和配置寄存器進行修改,結果顯示修改無效,表明PMP的鎖定功能是有效的。
2)M-Mode下分別對鎖定且無讀、寫和代碼執(zhí)行權限的PMP條目進行讀、寫與代碼執(zhí)行操作
輸出結果:
Enter Load Access Fault Exception Handler:
MCAUSE:0x30000005
MEPC:0x8000031e
Enter Store Access Fault Exception Handler:
MCAUSE:0x30000007
MEPC:0x8000032e
Enter Instruction Access Fault Exception Handler;
MAUSE:0x30000001
MEPC:0x80000380
結果分析:對條目鎖定后,依次在無讀、無寫和無代碼執(zhí)行權限下執(zhí)行內存的讀、寫和代碼執(zhí)行操作。分別觸發(fā)Load Access Fault(異常編號5)、Store Access Fault(異常編號7)和Instruction Access Fault(異常編號1)異常。異常編號可以從mcause CSR 最低字節(jié)看出,mcause CSR的[29:28]位為3(即二進制11),表明異常發(fā)生時所在的特權模式為M-Mode。
3)M-Mode下將mstatus CSR的MPRV字段置1后分別對無讀、寫權限的PMP條目的地址進行讀、寫操作
輸出結果:
Enter Load Access Fault Exception Handler:
MCAUSE:0x30000005
MEPC:0x8000032e
Enter Store Access Fault Exception Handler:
MCAUSE:0x30000007
MEPC:0x8000033a
結果分析:依次對PMP條目執(zhí)行無讀、無寫權限操作。分別觸發(fā)了Load Access Fault(異常編號5)、Store Access Fault(異常編號7),mcause CSR的[29∶28]位為3(即二進制11),表明異常發(fā)生時所在的特權模式為M-Mode。
4)U-Mode下分別對無讀、寫和代碼執(zhí)行權限的PMP條目包含的地址進行讀、寫操作
輸出結果:
Enter Load Access Fault Exception Handler:
MCAUSE:0x5
MEPC:0x8000034a
Enter Store Access Fault Exception Handler:
MCAUSE:0x7
MEPC:0x8000034a
Enter U-Mode:
Enter Instruction Access Fault Exception Handler:
MCAUSE:0x1
MEPC:0x80000380
結果分析:依次進行無讀、無寫和無代碼執(zhí)行權限操作。分別觸發(fā)了Load Access Fault(異常編號5)、Store Access Fault(異常編號7)和Instruction Access Fault(異常編號1)異常。mcause CSR的[29∶28]位為0(即二進制00),表明異常發(fā)生時所在的特權模式為U-Mode。
5)S-Mode下分別對無讀、寫和代碼執(zhí)行權限的PMP條目包含的地址進行讀、寫操作。
輸出結果:
Enter Load Access Fault Exception Handler:
MCAUSE:0x10000005
MEPC:0x80000340
Enter Store Access Fault Exception Handler:
MCAUSE:0x10000007
MEPC:0x80000340
Enter S-Mode:
Enter Instruction Access Fault Exception Handler:
MCAUSE:0x10000001
MEPC:0x80000380
結果分析:依次進行無讀、無寫和無代碼執(zhí)行權限操作。分別觸發(fā)了Load Access Fault(異常編號5)、Store Access Fault(異常編號7)和Instruction Access Fault(異常編號1)異常。mcause CSR的[29∶28]位為1(即二進制01),表明異常發(fā)生時所在的特權模式為S-Mode。
本文對一款RISC-V架構的安全處理器的特權模式與物理內存保護策略設計了測試方案,該方案為特權模式檢測、觸發(fā)不同特權模式間相互切換以及利用子過程調用實現(xiàn)指定地址的執(zhí)行訪問控制測試等技術問題提供了解決思路并設計了相應的測試用例程序。使用這些測試用例,對RISC-V特權模式和PMP內存權限控制的各種場景下有效性進行了測試,為RISC-V指令集架構處理器的安全特性測試工作提供了參考。