上一篇通过 Gatekeeper 实战,我们已经看到了 QSEECOM 在实际使用中的笨拙之处。本篇将从架构层面系统归纳 QSEECOM 的固有局限,并分析这些局限导致的安全后果。
1. QSEECOM 的底层机制:SMC 与共享内存
1.1 SMC:世界切换的硬件基础
所有 QSEECOM 通信最终都通过 SMC 指令完成世界切换。当 HLOS Kernel 的 QSEECom Driver 调用smc或smc #0时:
- CPU 从 Normal World EL1 陷入 Secure World EL3(Secure Monitor)
- Secure Monitor 保存 Normal World 的上下文
- Secure Monitor 根据功能号(SMC ID)路由到对应的 TZ 处理函数
- TZ 处理函数将请求分发给对应的 TA
- TA 处理完毕后,原路返回
SMC 调用号(SMC ID)定义了请求的类型,例如:
TZ_OS_START_APP_SMC_ID— 启动 TATZ_OS_SHUTDOWN_APP_SMC_ID— 关闭 TATZ_OS_SEND_CMD_SMC_ID— 发送命令TZ_OS_REGISTER_LISTENER_SMC_ID— 注册监听器
1.2 共享内存机制
QSEECOM 的数据传输依赖 ION 共享内存:
- Client 通过 ION 分配器申请一块连续的物理内存
- 这块内存被映射到 HLOS 用户态(Client 可以读写)
- 通过 ioctl 将该内存区域的信息告知 QSEECom Driver
- QSEECom Driver 通过 SMC 将内存的物理地址传递给 TZ
- TZ/QTEE 将该物理地址映射到 Secure World 的地址空间
- 双方通过这块共享内存交换数据
Send Modified Command允许 Client 传递 ION 文件描述符,使大块数据(如 DRM 视频帧)可以零拷贝地在 HLOS 和 TZ 之间传递,避免数据拷贝的性能开销。
2. QSEECOM 的安全考量
2.1 TA 沙箱化(Sandboxing)
QTEE 5.0 中,每个 TA 运行在独立的沙箱进程中:
- 每个 TA 有自己的虚拟地址空间,与其他 TA 隔离
- 堆和栈有 guard page 保护,可检测溢出
- TA 只能通过 QTEE 内核提供的 API 访问硬件资源
2.2 共享内存的安全考量
QSEECOM 基于 HLOS 和 TZ 共享同一块物理内存来交换数据。由于 HLOS 侧并非可信环境,共享内存的数据对 HLOS 是可见的:
- HLOS 可以随时读写共享内存中的数据
- TA 需要自行验证从共享内存读取的数据的完整性
- 如果 TA 需要保持数据的机密性,必须自行加密
这是 QSEECOM 共享内存模型的固有特点,TA 开发者需要在应用层面加以应对。
2.3 Client 身份识别
在 QSEECOM 模型中,TZ 对 HLOS Client 的身份识别能力有限:
- QSEECom Driver 在 kernel 层面只知道调用进程的 UID/GID
- 缺乏对 HLOS 用户态进程的细粒度身份信息
- 任何拥有
/dev/qseecom访问权限的进程都可以与 TA 通信
3. QSEECOM 的设计探讨
QSEECOM 作为第一代通信框架,在早期的 TrustZone 生态中满足了基本需求,但随着平台架构演进和安全需求提升,其设计上的一些局限逐渐显现。这些问题在 SMCInvoke 的底层重构中得到了系统性的解决,下一篇将展开讨论。
3.1 扁平通信模型与缺少 IDL
QSEECOM 本质上是一个请求-响应(Request-Response)的扁平模型:
- Client 发送一段字节(
send_buf),TA 返回一段字节(recv_buf) - 数据格式完全由 Client 和 TA 自行约定,没有接口定义语言(IDL)
带来的问题:
- 接口变更时,需要同时修改 Client 和 TA 的序列化代码,容易遗漏
- 协议不一致只能在运行时发现,可能导致内存损坏或安全漏洞
- 无法自动生成 stub/skeleton,开发效率低
相比之下,SMCInvoke 引入MINK IDL,可自动生成类型安全的代理代码,接口即文档。
3.2 缺乏对象模型与能力系统
QSEECOM 中不存在 “对象” 概念,只有命令通道。TA 间通信需要手动封装:
qsee_encapsulate_inter_app_message()qsee_decapsulate_inter_app_message()后果:
- 无法实现细粒度的权限控制(只能粗粒度地允许或禁止整个 TA)
- 无法传递对象引用,难以构建复杂的安全服务组合
- TA 之间无法直接 IPC,必须经过 QTEE 内核进行消息转发
SMCInvoke 基于 MINK 的Object + Capability模型,Object 引用本身就是不可伪造的访问令牌。
3.3 Client 身份信息不可达
这是 QSEECOM 被诟病最多的弱点之一。TA 的入口函数:
int32_ttz_app_cmd_handler(void*req,unsignedintreqlen,void*rsp,unsignedintrsplen);没有任何参数传递调用者的身份(如 UID、PID、selinux 上下文)。TA 只能通过其他带外机制(如预先共享密钥)尝试区分调用者,但本质上无法防止伪造。
影响场景:
- Keymaster TA 需要知道是哪个 App 请求生成密钥
- DRM TA 需要区分不同的客户端进程以实施不同的策略
- 安全日志需要记录是哪个 HLOS 进程发起的操作
SMCInvoke 通过IClientEnv对象将调用者的凭证(credentials)传递给 TZ,TA 可根据凭证做访问控制。
3.4 共享内存攻击面
QSEECOM 的共享内存区域在 Normal World 和 Secure World 之间暴露。HLOS 侧(可能是恶意操作系统或带 root 权限的进程)可以随时读写该内存:
- 机密性风险:如果 TA 将敏感数据(如明文密钥)放入共享内存而未加密,HLOS 可直接窃取
- 完整性风险:HLOS 可以篡改共享内存中的请求或响应,TA 必须自行验证完整性(如添加 MAC)
- 重放攻击:没有内在机制防止 HLOS 重放之前的合法请求
已知攻击案例(高通文档提及):
- BitsPlease:攻击者攻破 QTEE 内核后导致 Keymaster 密钥泄露,部分原因是共享内存验证不充分
- CLKSCREW:利用调试内核攻破 TA 认证
- Meltdown/Spectre:利用 CPU 预测执行跨世界读取共享内存中的秘密
SMCInvoke 通过Memory Object明确限定共享范围,并由 Hyp Invoke Router 对参数做额外审查,减少攻击面。
3.5 可扩展性不足
| 局限 | 说明 |
|---|---|
| 单 TA 绑定 | 一个 Client 只能与一个 TA 通信(通过一个handle),与多个 TA 通信需要多次 load/unload |
| Listener 重模型 | 每个 Listener 需要一个独立阻塞线程,不适合大量轻量级回调 |
| 无服务发现 | Client 必须硬编码 TA 名称,无法通过标准接口枚举可用 TA |
| 无引用计数 | QSEECom_handle无引用计数,不能安全地在多个 Client 间共享 TA 会话 |
3.6 未考虑 Hypervisor 虚拟化
从 骁龙SM8350 开始,高通引入QHEE Hypervisor(运行在 EL2)。HLOS 的 SMC 调用首先被 Hypervisor 截获,再转发到 TZ。QSEECOM 设计时未考虑这一中间层:
- 在虚拟化场景(如 Trusted VM)下,HLOS 可能运行在 Guest VM 中,其物理地址是 GPA(Guest Physical Address),需要 Hypervisor 翻译为 IPA 或 PA
- QSEECOM 的共享内存物理地址直接传递给 TZ,无法处理 GPA 翻译
SMCInvoke 架构中明确包含Hyp Invoke Router,在 EL2 验证和翻译 SMC 参数,天然适配虚拟化环境。
4. 从 QSEECOM 到 SMCInvoke
下表总结了 QSEECOM 与 SMCInvoke 的关键差异:
| 特性 | QSEECOM | SMCInvoke |
|---|---|---|
| 通信模型 | 请求-响应(扁平) | 面向对象 Invoke |
| 接口定义 | 无(自定义结构体) | MINK IDL |
| 身份传递 | 无 | IClientEnv 携带凭证 |
| 能力系统 | 无 | Object Capability |
| TA 间通信 | 手动封装/解封消息 | 原生 IPC |
| 大块数据传输 | ION fd (Send Modified) | IMemRegion 对象 |
| Hypervisor 支持 | 无 | Hyp Invoke Router |
| 服务发现 | 硬编码 TA 名称 | IClientEnv → IAppLoader |
| 回调机制 | Listener(笨重) | Callback Object(轻量级) |
| 安全粒度 | TA 级别 | Object/Operation 级别 |
已知安全分析
高通在文档中提到了推动迁移的部分安全动因——BitsPlease(QTEE 内核被攻破导致 Keymaster 密钥泄露)、CLKSCREW(利用调试内核攻破 TA 认证)以及 Meltdown/Spectre 等侧信道攻击。这些案例表明,仅将密钥置于 TZ 软件中并不充分,还需要更精细的能力控制和更小的可信计算基(TCB),这正是 SMCInvoke 的设计目标之一。
| 威胁类别 | QSEECOM 弱点 | 潜在后果 |
|---|---|---|
| 身份伪造 | 无身份传递 | 任何进程可冒充合法 Client |
| 共享内存篡改 | HLOS 可读写共享内存 | TA 数据被篡改或泄露 |
| 无 IDL 约束 | 协议手动实现 | 接口不一致导致内存安全漏洞 |
| 引用缺失 | 无 Capability | TA 访问控制过粗 |
| Hypervisor 缺失 | 直接 SMC | 无法在虚拟化环境下安全运行 |
这些局限共同构成了高通从 QSEECOM 迁移到 SMCInvoke 的核心技术驱动力。
10. 总结
QSEECOM 作为高通第一代 HLOS↔TZ 通信框架,在 TrustZone 生态中发挥了重要作用。它通过 QSEECom Driver + SMC + 共享内存的组合,让 HLOS 客户端能够调用 TA 的安全服务,并通过 Listener 机制支持反向通信。
随着平台架构演进(Hypervisor 引入、Trusted VM 虚拟化)和安全需求提升,QSEECOM 在通信模型、身份验证、能力控制等方面的设计局限逐渐显现。SMCInvoke 基于 MINK 微内核的 Object Invocation 和 Capability 模型,对底层通信架构进行了系统性重构,在下一篇中我们将深入探讨其设计与实现。