一款安全RISC-V处理器特权模式和内存保护测试

2021-07-19 06:39焦芃源李翔宇殷树娟
关键词:寄存器特权条目

焦芃源,李 涵,李翔宇,殷树娟

(1.北京信息科技大学 理学院,北京 100192;2.清华大学 微电子学研究所,北京 100084)

0 引言

为保证嵌入式设备中存储的个人隐私信息不被窃取,采用一个安全的处理器至关重要。特权模式和物理内存保护是安全嵌入式处理器的必备特性。ARM Cortex- M3架构处理器支持两种特权模式对程序访问存储器的操作做出限制[1]。x86架构处理器划分为4个特权模式,称之为保护环[2]。这种分级隔离执行[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架构中的特权模式切换与物理内存访问控制这两个处理器安全特性设计了一套测试方案,并进行了测试。

1 RISC-V处理器的安全特性

RISC-V指令集架构有3种特权模式:机器模式(machine mode,M-Mode)、用户模式(user mode,U-Mode)和监管者模式(supervisor mode,S-Mode)[9]。其中M-Mode是所有RISC-V处理器必须具备的特权模式,也是处理器上电后的默认模式。M-Mode对整个系统资源具有最高的访问权限。但在运行不可信代码时,仅具有M-Mode的处理器不能保护系统免受不可信代码的侵害,故处理器应增加U-Mode和S-Mode特权模式和PMP来限制不可信代码的行为。U-Mode一般运行不可信的用户代码,其权限最低。S-Mode的权限介于M-Mode和U-Mode之间。PMP是一个为物理内存空间指定读写和代码执行权限的单元,在一些资源有限的嵌入式系统中可以以较低的开销实现内存访问控制。PMP最多支持16个条目对内存空间进行划分,每个条目定义一个需要限制访问权限的内存地址区间,每个条目由一个配置寄存器和地址寄存器来描述。配置寄存器具有锁定(L)、地址匹配模式(A)以及代码执行(X)、读(R)和写(W)字段,结合地址寄存器对内存空间的访问进行控制。特权模式和PMP可对处理器的运行提供安全保护,故应对这些特性的有效性进行测试。

2 RISC-V处理器安全特性测试

2.1 测试对象

本文对一款32位RISC-V安全处理器的3种特权模式和PMP的内存保护机制进行测试。被测处理器是一个简单片上系统(system on chip,SoC)。该SoC包含一个RISC-V 32位处理器核心、512 KB的指令存储器和256 KB的数据存储器,并集成了JTAG (joint test action group)、UART(universal asynchronous receiver/transmitter)等外围设备。外围设备中的JTAG和UART与PC机通过USB口相连,用作测试程序的下载、调试、运行以及运行结果的输出。测试程序源代码采用C和RISC-V汇编语言混合编写并使用RISC-V交叉编译工具链对程序进行编译、汇编与链接生成可执行程序。调试和运行的结果通过串口终端打印进行显示。

2.2 测试方案

2.2.1 处理器特权模式切换测试

低特权模式的不可信代码执行越权操作或者进行系统调用时应触发异常,默认交由最高特权模式M-Mode的异常例程进行处理。在存在异常委托的情况下,低特权模式触发的异常也可以委托给S-Mode的异常例程处理。因此应测试处理器在U-Mode下执行了越权操作或者进行系统调用后能否触发M-Mode的异常;在U-Mode系统调用委托给S-Mode的情况下,U-Mode的系统调用是否能够通过异常委托的方式进入到S-Mode;在S-Mode下执行越权操作或进行系统调用后能否触发M-Mode异常。

RISC-V处理器中具有一些特殊指令和控制状态寄存器(control status registers,CSR)用来控制和指示处理器硬件的状态。具体地,mret是M-Mode异常退出指令,mstatus CSR是M-Mode下指示处理器状态的寄存器。mstatus CSR的MPP字段用于切换特权模式时保存切换前的特权模式,其中MPP字段00代表U-Mode,01代表S-Mode,11代表M-Mode。将mstatus CSR的MPP字段写入对应的值,执行mret指令后,处理器应根据mstatus的MPP字段恢复特权模式,来达到特权模式的切换。若写入01,就切换到S-Mode,若写入00,就切换到U-Mode。

S-Mode向其他模式切换也可采用类似的方法。sret是S-Mode异常退出指令。sstatus CSR是S-Mode下指示处理器状态的寄存器,与mstatus CSR类似,sstatus CSR的SPP字段中0代表U-Mode,1代表S-Mode。故通过写0到sstatus CSR的SPP字段,然后执行sret异常退出指令可切换到U-Mode。S-Mode到M-Mode的切换通过调用ecall指令触发环境调用异常来实现。

U-Mode下切换到M-Mode可以直接调用ecall指令,从而进入到M-Mode的异常例程。RISC-V中默认任何特权模式下发生的异常均会交由M-Mode来处理。若要从U-Mode切换到S-Mode,也可以使用ecall指令,但需要在U-Mode下执行ecall指令触发用户环境调用异常之前将该异常委托给S-Mode来处理。medeleg CSR是异常委托寄存器。在M-Mode下应将medeleg CSR寄存器中对应用户环境调用异常的字段置1实现用户环境调用异常的委托。然后需要在ecall指令的异常例程代码中保存通用寄存器上下文,并将sepc CSR的值自增4,这么做是因为sepc CSR保存的是异常发生时指令的地址,退出异常时处理器会根据sepc CSR指定地址的指令执行从而重新触发异常。若要程序继续执行下去,应将sepc CSR指向发生异常的指令的下一条指令。要使得处理器能成功从U-Mode跳入S-Mode异常例程,还需要将该异常例程的入口地址存入stvec CSR。

为确定特权模式切换是否成功,必须要对处理器当前所处的特权模式进行检测。但是RISC-V处理器中不存在反映当前处理器所处特权模式的寄存器,因此只能采用间接的方法测试。本文设计了执行每种Mode下合法指令和非法指令的特权模式检测方法。mstatus CSR是M-Mode下指示处理器状态的寄存器。例如由M-Mode切换到S-Mode后,读mstatus CSR操作非法而读sstatus CSR合法,而由M-Mode切换到U-Mode后,读mstatus和sstatus操作均非法。非法指令会触发非法指令异常,通过串口打印输出mcause CSR、mepc CSR的值可以观察发生的异常类型、异常发生时指令的地址,该地址可以通过objdump工具对可执行程序进行反汇编来确定发生异常指令的地址是否为待测非法指令的地址。

特权模式切换的整体测试流程如图1所示,一共有3个测试分支。首先处理器上电默认进入M-Mode。PMP所有条目字段默认为0。通过对PMP条目的地址寄存器和配置寄存器进行初始化配置,将处理器的指令存储和数据存储划分为若干区间,默认所有PMP条目均不锁定且具有读写和代码执行权限。接下来完成特权模式切换的测试。特权模式切换采用M → U→ M→ S→ U→ S→ M的顺序,这样的转换次序既将6种可能的模式切换方式都包括在内,又在程序的实现上比较容易。其中U→ M和U→ S都是在U-Mode下执行了ecall指令,触发环境调用异常后却分别切换到不同的特权模式,从而测试了异常委托的有效性。此外,通过读mstatus CSR和sstatus CSR是否触发非法指令异常也间接测试了模式切换的正确性。

图1 处理器特权模式切换测试方案流程

2.2.2 PMP内存访问控制测试

PMP配置和地址寄存器的不同设定对运行在3种特权模式下的代码有着不同的内存访问限制。对内存进行非法的读、写与代码执行操作均应触发高特权模式的异常并交由高特权模式进行处理。因此应分别测试在M-Mode下,对锁定的PMP条目的地址与配置寄存器的修改能否被禁止,对锁定的PMP条目内存地址空间的读写与代码执行控制是否有效。此外,mstatus CSR的MPRV字段若置1,M-Mode下的内存读写操作也应符合PMP权限控制规则。故应测试mstatus CSR的MPRV字段置1时对未锁定但无读写权限的PMP条目内存地址空间的读写操作能否被禁止。另外还应测试在S-Mode和U-Mode下对PMP条目内存地址空间进行读写与代码执行操作的控制是否有效。

为测试内存的读、写权限控制是否有效,可以分别将PMP条目的配置寄存器的R、W字段置0,然后读、写该条目地址寄存器规定范围内的地址,并观察是否触发Load Access Fault或Store Access Fault异常。为了确定触发的异常类型,可以在异常例程中输出mcause CSR的值,然后通过串口打印这些寄存器的值来检验。对内存代码执行权限控制是否有效的测试,我们采用子过程调用的方法,将一段待测代码封装为一个子过程。为了使得测试程序对这个子过程不具有代码执行权限,需要确定该子过程在内存中所处的地址范围。具体地,可以在测试程序中定义一个子过程并编写测试程序其他部分,再将测试程序编译汇编链接成可执行文件后使用objdump将可执行文件进行反汇编来确定子过程所处的地址段。之所以不采用地址跳转的方式,是因为测试程序的改动可能会改变待测子过程的地址,不便于PMP地址寄存器的配置。在PMP锁定功能的测试中,可通过将PMP条目的配置寄存器锁定位写入1来锁定条目。由于PMP条目锁定后对该条目的配置与地址寄存器的修改不会触发异常,可通过分别在锁定条目前、后修改寄存器值的对比来确定锁定操作是否有效。

PMP内存访问控制测试方案的流程如图2所示,共分为5个测试分支。被测处理器中配置有8个PMP条目。因为代码执行权限的测试需要有指令执行,故PMP管理的内存应包括数据存储空间和指令存储空间。在被测处理器中指令和数据分别存储在两个存储器中。为了全面测试数据和指令的访问控制,在处理器上电后PMP条目初始的配置是8个PMP条目的地址寄存器中前4个地址区间位于指令存储器中,接下来的3个地址区间位于数据存储器中。因为U-Mode和S-Mode默认对不在PMP条目中的地址不具有访问权限,为了能够在U-Mode和S-Mode下通过串口输出信息,将最后1个PMP条目的地址寄存器的值设置为UART外设映射在内存中的地址。8个PMP配置寄存器LXWR字段的初始值为0111,即不锁定且可读可写可执行。

图2 PMP内存访问控制测试方案流程

在测试1中,可以锁定一个PMP条目进行测试。首先在条目未锁定时串口打印该条目的配置和地址寄存器的值,然后修改、锁定并打印出它们的值,锁定后再修改该条目的地址和配置寄存器的值,并打印PMP条目寄存器的值检验修改是否生效。

在测试2中,PMP初始设置与测试1相同。首先可以修改一个PMP条目的配置寄存器只有写或只有读权限并锁定,然后对该条目进行读和写操作观察串口打印的异常信息。在代码执行权限的测试中,我们将PMP条目的地址寄存器配置成被调用子过程的地址区间。由于PMP规则要求条目的地址区间4字节对齐,可以通过在测试程序中子过程的前后加上4字节对齐伪指令来实现。测试程序修改PMP条目的配置寄存器不具有代码执行权限并锁定,然后调用该子过程观察串口打印的异常信息。

在测试3中,仅需再做内存读写操作之前修改mstatus CSR 的MPRV字段为1即可,内存的读写测试可以复用测试2的代码。

在测试4和测试5中,分别令程序进入U-Mode或者S-Mode,然后对不匹配任何PMP条目的地址进行读和写操作,观察串口打印的异常信息。而对匹配了PMP条目的地址的读、写与代码执行的操作可以复用测试2中内存访问测试的代码。

2.3 测试结果分析

2.3.1 特权模式切换测试结果与分析

特权模式切换的测试根据图1的流程分为3个测试项,测试结果输出如下。

1)处理器能否切换至U-Mode

输出结果:

Enter Illegal Instruction Exception Handler:

MCAUSE:0x2

MEPC:0x80000322

结果分析:程序中读sstatus CSR操作后输出mcause CSR的值为0x2,最低字节表明触发了Illegal Instruction Fault 异常(异常编号2),对应的第[29∶28]位为二进制的00,指示触发异常前已切换到U-Mode。

2)处理器能否切换至S-Mode

输出结果:

Enter Illegal Instruction Exception Handler:

MCAUSE:0x18000002

MEPC:0x80000380

结果分析:程序中读sstatus CSR操作没有触发异常,读mstatus CSR后mcause CSR的值输出为0x18000002,最低字节表明触发了Illegal Instruction Fault 异常(异常编号2),第[29∶28]位为二进制的01,指示触发异常前已切换到S-Mode。

3)M→U→M→S→U→S→M不触发非法指令异常的切换流程

输出结果:

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下执行ecall指令进入到M-Mode的用户环境调用异常处理程序。退出异常后修改medeleg CSR将U-Mode的环境调用异常委托给S-Mode,该修改过程没有触发异常,表明处理器处于M-Mode。并且之后通过M→S→U模式切换后执行ecall指令,进入到委托给S-Mode的用户环境调用异常处理程序。退出异常处理程序后处理器处于S-Mode,再执行ecall指令,进入到监管者环境调用异常处理程序中。退出异常后回到M-Mode,程序结束。结果表明6种模式切换方式均可实现。

2.3.2 PMP内存访问控制测试结果与分析

PMP内存访问控制的测试根据图2的流程分为5个测试项,测试结果输出如下。

1)PMP条目锁定后修改条目的配置和地址寄存器

输出结果:

PMPADDR:0x24004fff PMPCFG:0x1f

PMPADDR:0x24005fff PMPCFG:0x9f

PMPADDR:0x24005fff PMPCFG:0x9f

结果分析:PMP条目寄存器值的输出结果第一行为初始化值打印,而第二行为修改未锁定条目的寄存器的值且修改成功,第三行为对条目锁定后对地址和配置寄存器进行修改,结果显示修改无效,表明PMP的锁定功能是有效的。

2)M-Mode下分别对锁定且无读、写和代码执行权限的PMP条目进行读、写与代码执行操作

输出结果:

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

结果分析:对条目锁定后,依次在无读、无写和无代码执行权限下执行内存的读、写和代码执行操作。分别触发Load Access Fault(异常编号5)、Store Access Fault(异常编号7)和Instruction Access Fault(异常编号1)异常。异常编号可以从mcause CSR 最低字节看出,mcause CSR的[29:28]位为3(即二进制11),表明异常发生时所在的特权模式为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条目执行无读、无写权限操作。分别触发了Load Access Fault(异常编号5)、Store Access Fault(异常编号7),mcause CSR的[29∶28]位为3(即二进制11),表明异常发生时所在的特权模式为M-Mode。

4)U-Mode下分别对无读、写和代码执行权限的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

结果分析:依次进行无读、无写和无代码执行权限操作。分别触发了Load Access Fault(异常编号5)、Store Access Fault(异常编号7)和Instruction Access Fault(异常编号1)异常。mcause CSR的[29∶28]位为0(即二进制00),表明异常发生时所在的特权模式为U-Mode。

5)S-Mode下分别对无读、写和代码执行权限的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

结果分析:依次进行无读、无写和无代码执行权限操作。分别触发了Load Access Fault(异常编号5)、Store Access Fault(异常编号7)和Instruction Access Fault(异常编号1)异常。mcause CSR的[29∶28]位为1(即二进制01),表明异常发生时所在的特权模式为S-Mode。

3 结束语

本文对一款RISC-V架构的安全处理器的特权模式与物理内存保护策略设计了测试方案,该方案为特权模式检测、触发不同特权模式间相互切换以及利用子过程调用实现指定地址的执行访问控制测试等技术问题提供了解决思路并设计了相应的测试用例程序。使用这些测试用例,对RISC-V特权模式和PMP内存权限控制的各种场景下有效性进行了测试,为RISC-V指令集架构处理器的安全特性测试工作提供了参考。

猜你喜欢
寄存器特权条目
精神病患者暴力降阶技术专家共识与形成方法探讨
无聊是一种特权
不允许任何人有超越法律的特权:《毛泽东给雷经天的信》
不允许任何人有超越法律的特权:《毛泽东给雷经天的信》
常用电子测速法在某数字信号处理器中的应用*
《词诠》互见条目述略
飞思卡尔单片机脉宽调制模块用法研究
移位寄存器及算术运算应用
不服不行的搜索记录
两本《醒世姻缘传》?