安全之安全(security²)博客目录导读
目录
一、OPTEE标准的异常调用栈格式
二、OPTEE异常调用栈解析脚本
三、如何执行解析命令
四、OPTEE异常调用栈解析结果
序言:当OPTEE发生异常时,安全控制台会输出dump信息,虽然有了Call stack,但是仅有函数的地址,并不知道确切的调用关系,尚且不能精准定位问题。因此就需要本节的知识对异常调用栈进行精确解析。
一、OPTEE标准的异常调用栈格式
当OP-TEE遇到严重的错误情况时,它将诊断信息打印到安全控制台。如果CFG_UNWIND=y(默认启用),则消息包含一个调用栈。
以下错误将触发dump:
1)在TEE内核(内核模式)或TA(用户模式)中的数据或预取中止异常;
2)当用户模式TA发生panic时,无论是通过直接调用TEE_Panic()还是由于TEE Core Internal API检测到的某些错误,
3)当TEE core检测到致命错误并决定挂起系统时,因为没有办法安全地进行(core panic)。
这些信息看起来略有不同,取决于:
1)错误是异常还是panic,
2)异常发生时的异常/特权级别(如果用户模式TA正在运行,则为PL0/EL0,如果是TEE core,则为PL1/EL1);
3)TEE和TA是32位还是64位,
4)异常的确切类型(数据或预取中止、translation fault、读写权限错误、对齐错误等)。
下面是在32位TEE内核(QEMU)上运行的32位可信应用程序中的一个panic示例:
上面的dump是由TA在输入一个不可恢复的错误时触发的,该错误最终导致TEE_Panic(0)调用。从dump中可以看出,虽然有了Call stack,但是仅有函数的地址,并不知道确切的调用关系,尚且不能精准定位问题,也就是序言里提到的问题。
二、OPTEE异常调用栈解析脚本
OP-TEE提供了一个名为symbolize.py的脚本,以促进对此类问题的分析。它位于script /symbolize.py中的OP-TEE OS源代码树中,也被复制到TA开发工具包中。每当遇到报告严重错误并包含“Call stack:”行的错误消息时,都可以使用该脚本。它应该在主机(host)系统(构建环境)上运行,而不是在目标(target)系统上运行。以qemu_v8环境举例,也就是说在执行make -f qemu_v8.mk run-only命令的主机上运行该脚本。
symbolize.py从stdin读取其输入,并将扩展的调试信息写入stdout。-d(目录)选项告诉脚本在哪里查找一个或多个ELF文件(<uuid>.stripped.elf)或tee.elf (TEE core)。详细信息请参考symbolize.py --help。
三、如何执行解析命令
1、直接将异常dump作为stdin输入
1)先执行./optee_os/scripts/symbolize.py -d ./optee_examples/*/ta
2)然后将异常dump信息拷贝至执行脚本的控制台
3)执行完后可以看到实际的调用栈解析,Ctrl+D退出脚本
2、将异常dump保存为.txt文件,然后输入
1)将异常dump保存为dump.txt,假如和symbolize.py为同一个目录
2)直接执行cat dump.txt | ./optee_os/scripts/symbolize.py -d ./optee_examples/*/ta
3)实际的调用栈解析直接打印,并自动退出脚本
四、OPTEE异常调用栈解析结果
第三节中的两种方式可自由选择,不管使用哪一种,都可以输出实际的调用栈解析。Python脚本使用GNU Binutils包中的几个工具来执行以下任务:
1)将调用栈地址转换为函数名、文件名和行号。
2)将中止地址转换为一个符号加上一些偏移量或一个ELF section加上一些偏移量。
3)打印TA的每个内存区域中包含的ELF section的名称。
我们可以很清楚地看到具体哪个文件的哪个函数的哪一行,精确定位问题,至此序言中的问题得到有效解决。
注意:要成功运行symbolize.py,还必须使工具链在PATH中可见(即,export PATH=<my-toolchain-path>/bin:$PATH)。
参考:Abort dumps / call stack — OP-TEE documentation documentation