请问如果EL1里面运行的内核调用了一个SMC指令(通过SMC去请求secure world的服务),然后这个调用被运行在EL3的ARM-Trusted-Firmware(EL3运行的相当于monitor)接收到了,这个时候EL3能否按照EL1的地址映射方式去访问EL1里面的虚拟内存?(在访问的时候还没有切换到secure os的context)
比如,EL1里面运行的是linux内核,linux内核空间的虚拟地址为addr1(比如sys_call_table),然后我试图在EL3里面直接通过
memcpy(dest, addr1_of_sys_call_table, size);
这种方式来访问,但是导致系统卡住了,也没有提示访问错误之类的。
我是在smc_handler一开始就访问的,所以应该不会存在什么context破坏的问题(TTBR0_EL1, TTBR0_EL3我都没有动过),除非是smc调用本身会造成一些context的转换,又或者是因为EL3级别使用的是TTBR0_EL3而不是TTBR0_EL1? 如果是这样的话,可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table吗?
如果不可以的话,那请问有什么办法在EL3(monitor)级别或者secure-EL1(secure os)级别访问到EL1(normal world)的一些资源呢?
我对于这块还只能算是初学者,提前谢谢大家!
欢迎提问,本问题移动到中文社区
Hi yzh07137,
我对ARMv8还不太了解,El3为什么要访问EL1的资源呢?
Normal world和Secure world之间可以通过registers和ShareMemory访问咨询,比如加载Trusted Application等,ShareMemory是non-secure,可以被Normal access 和Secure Access访问。
GlobalPlatform TEE Client API和 optee_os/optee_design.md at master · OP-TEE/optee_os · GitHub 中有相关描述, 希望对你有用。
多谢ethanzhang和yupluo01帮忙解答
请 楼主看一下
在ethanzhang的基础上在补充一下。
每个EL, 还有同一个EL(比如EL1)的secure和non-secue下都有自己TTBR, MMU和Cache的配置。
kernel代码在执行SMC切换到EL3, ARM trusted firmware里面后,会使用自己的MMU,TTBR0_EL3的配置。
若涉及到memory访问,需要传递物理地址。
有个代码的例子,供参考:
Linux kernel传递指针给ARM trusted firmware的时候,是物理地址。 比如PSCI CPU ON的代码:
arch/arm64/kernel/psci.c
static int cpu_psci_cpu_boot(unsigned int cpu)
{
int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry));
......
}
不了解你想在EL3访问non-secure EL1的什么资源? 假如是memory的话,只要传递PA就可以了,当然EL3的MMU要配置好。
Hi, ethanzhang
谢谢你的回复,确实是通过SharedMemory来访问的,但是这样secure world就完全不知道normal world里面发生的事件,这个smc不知道是不是正常的请求还是恶意的。
我是看有几篇论文都说了检查EL1里面某些关键内存的值,所以我想尝试一下看看能不能访问到EL1里面linux内核的比如sys_call_table的内容,但是一访问就hung了。我是把TTBR0_EL1的值赋值给了TTBR0_EL3, 然后想让EL3在smc_handler里面去按照normal world的方式去访问(因为我想着EL3是最高的特权级,应该是可以访问所有内存的).
谢谢你的回复,
我是想在每次non-secure EL1执行一个smc调用的时候,在EL3里面的smc_handler里面去访问EL1里面一些关键内存的值,比如在转换context之前去访问一下sys_call_table的内容。
是的,手册上说它们使用的是不同的mmu,那是不可以强行指定使用EL1的MMU来按照normal world的方式来访问内存吗?
不过你说传递的是物理地址的话,这确实可以说的通了,但是我并没有使用到SMC调用传递的物理地址,而是直接指定的立即数当作地址,这种情况下不是应该会被当作虚拟地址吗。另外请问一下你说的,arm-tf使用自己的MMU, 配置TTBR0_EL3,但是我好像没有在代码里面看有关于内存管理的部分,,不知道是不是我看漏了。
如果是传递的物理地址的话,请问有没有办法让它按照EL1的方式去访问呢?
我在想,如果跨EL不可以共享页的话,那么Non-secure EL1和Secure EL1是否可以设置对方的页表并且按照对方的虚拟地址映射方式去访问?
另外顺便请问一下,有没有哪个寄存器可以让Non-secure EL1对于TTBR\SCTLR这些寄存器的访问,统统给trap到EL3来? 我看armv8的手册都是说可以trap到EL2, 但是好像没有那个寄存器可以给trap到EL3来。
在设计Trusted OS时会考虑到你提到的问题,一般是把monitor做的比较简单,主要做switch world。但是在设计Trusted OS和Trusted Application时一般都认为所有Normal world的request是Non-trusted,都会check Security。所以安全检查机制一般都放到Trusted OS或者Trusted Application中实现。
Hi, ehanzhang,
能请教一下Trusted OS有什么方法可以访问normal world的一些内存内容吗,因为Trusted OS似乎使用的是ttbr1_el0,和normal world也不是一套页表,还是需要转换页表才能访问。
如果单纯根据传递过去的参数判断的话又起不到安全的作用,因为参数主要还是当作请求的TA的类型,secure world根据参数是无法判断normal world目前的状态,如果被攻击了,直接冒充正常用户去发送这个请求,Trusted OS是无法知道到底合不合法的。
原来是我搜索文档的关键词不对,,,现在找到几个可以trap的寄存器了
这个要根据Trusted OS的实现有关,ShareMemory是可以被Rich OS和Trusted OS访问的,例如在OP-TEE初始化中会根据配置建立页表,ShareMemory的Physical Address和Size都是保存在全局变量,运行在Rich OS下的Trustzone Driver通过fastcall向Trusted OS发送请求获取ShareMemory信息,OPP-TEE design doc中介绍了ShareMemory的用途,你可以看下加载TA 的Source Code里面有对TA signed ELF进行校验,希望对你理解ShareMemory 有用.
谢谢,抱歉之前忘了回。现在看来好像并不能在TEE里面主动去访问Normal world,感觉大部分还是做成的是一个安全隔离的环境
请问如果EL1里面运行的内核调用了一个SMC指令(通过SMC去请求secure world的服务),然后这个调用被运行在EL3的ARM-Trusted-Firmware(EL3运行的相当于monitor)接收到了,这个时候 EL3能否按照EL1的地址映射方式去访问EL1里面的 虚拟内存?(在访问的时候还没有切换到secure os的context)
不可以,EL1和EL3使用各自的MMU表
可以将addr1转化为物理地址,作为参数传递给EL3,EL3再将该地址映射到自己的MMU表中就可以访问了
我 是在smc_handler一开始就访问的,所以应该不会存在什么context破坏的问题(TTBR0_EL1, TTBR0_EL3我都没有动过),除非是smc调用本身会造成一些context的转换,又或者是因为EL3级别使用的是TTBR0_EL3而不是 TTBR0_EL1? 如果是这样的话,可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table吗?
不可以强行暂时把TTBR0_EL1的值赋给TTBR0_EL3然后去直接访问addr1_of_sys_call_table,你在EL3中的代码和变量就访问不了了,程序就死掉了
传递物理地址,再将物理地址隐射到对应的MMU表
Yuping Luo的回答是正解