前言
上一篇指出 HWASAN 借助指针掩码扩展从测试工具走向生产工具,但单一机制覆盖的威胁面有限:sanitizer 主要查内存访问越界,对控制流劫持与权限滥用无能为力;硬件隔离机制保护的是区域边界,对区域内部的逻辑漏洞无从感知。内存安全的工程现实要求多层机制叠加而非任选其一。
本文梳理 RISC-V 上三层防御——Sanitizer、控制流完整性(CFI)、硬件隔离——的职责边界与协同模式,讨论生产构建中如何选型与组合。
一、内存安全威胁的分层
工程实践将内存安全威胁分为两层与三类漏洞:
| 层次 | 威胁 | 典型漏洞 |
|---|---|---|
| 时空内存安全 | 访问未经授权的内存位置 | 越界读写、释放后使用、双释放 |
| 控制流安全 | 跳转至非预期目标 | 间接调用劫持、返回地址覆盖 |
两层威胁的检测手段可以独立存在,但实际攻击链常跨层:控制流劫持正是借助时空内存安全漏洞(如栈溢出)写入返回地址,进而完成跳转。三层防御的设计目标是让攻击链在任一环节失败时即被阻断。
二、Sanitizer 层:覆盖时空内存安全
ASAN/HWASAN 的工作集中在时空内存安全维度。上一篇已讨论的指针掩码加速路径,是从软件影子机制走向硬件标签机制的关键工程进步,但其在生产构建中的角色仍要分场景讨论:
- 测试期:以覆盖率为优先目标,可同时启用 ASAN、UBSan 等多个 sanitizer,代价由开发流程承担
- 生产期:以性能为优先目标,仅保留 HWASAN 硬件路径,关闭软件影子
- 长期生产:评估 sanitizer 的运行时开销对用户可感知延迟的影响,决定是否保留
Sanitizer 层的局限在于它不查控制流。攻击者若能通过合法接口构造合法调用(仅参数异常),sanitizer 无任何违规可报。
三、控制流完整性层:覆盖控制流安全
RISC-V 的 CFI 由两个独立扩展分别处理前向分支与后向返回:
| 扩展 | 覆盖方向 | 机制概要 |
|---|---|---|
| Zicfilp | 前向间接分支 | 间接调用/跳转目标地址须落在指定的着陆标签点 |
| Zicfiss | 后向返回 | 每次调用将返回地址的加密/摘要写入影子栈,返回时校验 |
两条路径互补:前向分支的着陆点保证间接跳转不能落到任意位置,后向影子栈保证 ret 指令不能跳到调用方之外的任何地址。RISC-V 的设计选择与 Arm 的 BTI/PAC 同源,但落地机制不同——具体指令编码与 CSR 状态字段以规范文本为准,编译器和运行时支持是真正决定可用性的环节。
CFI 的工程价值在于它对运行时开销极低,着陆点检查与影子栈校验均为常量时间,可作为生产构建的默认启用项。
四、硬件隔离层:兜底区域边界
PMP 在内存安全链中的位置是"兜底":sanitizer 漏报或 CFI 校验被绕过时,PMP 限制的内存区域阻止越权访问。其工程要点已被前作多次讨论,本文强调其在多层架构中的两项约束:
- 粒度选择。PMP 条目数有限,配置应留给最关键的代码段与数据段,过度配置反而稀释每条条目的保护范围。
- 可逆性。与 IOMMU 配合形成"区域边界 + 设备访问边界"的双层防御,是目前通用处理器可达的较强组合。
五、多层协同模式
将上述三层按代价与覆盖率组织,典型的生产构建配置可表述为:
| 层级 | 启用策略 | 运行时代价 | 覆盖率 |
|---|---|---|---|
| HWASAN(硬件路径) | 生产构建按目标平台能力选择性启用 | 低 | 时空内存安全 |
| CFI(Zicfilp + Zicfiss) | 默认启用 | 极低 | 控制流安全 |
| PMP 区域隔离 | 固件启动时配置 | 零运行时 | 区域边界 |
各层之间的协同不是叠加运行,而是各自处理不同威胁面。三层并存时攻击链需同时绕过三类机制,工程成本远高于单层突破。这并不意味着部署了全部机制即可声称"内存安全"——漏洞研究不断发现新攻击面,多层防御的稳定性来自对每个层级能力的清晰认识,而不是层级数量。
六、平台适配与权衡
三层防御的实际价值高度依赖目标平台的扩展实现状态。部署前应逐项核实:
- HWASAN:编译器与运行时库的适配版本、动态加载器与 C 库的 longjmp 支持
- CFI:工具链是否默认开启着陆点标签与影子栈、第三方库的兼容状态
- PMP:固件层面的配置正确性、运行时观测命令的可用性
工程权衡通常围绕两点展开。其一是性能预算对 HWASAN 启用与否的决定:5%–15% 的开销(上一篇文章给出的经验区间)在多数服务场景可接受,在部分实时场景则需要评估。其二是 CFI 的二进制兼容要求:未按 CFI 编译的库与已按 CFI 编译的代码混合部署,可能触发意外的着陆点校验失败,处理方式是按模块或按发行版统一编译策略。
结语
多层防御的核心思想是把"无法用单一机制覆盖的威胁面"交给对应层处理。Sanitizer 处理时空内存安全,控制流完整性处理控制流安全,PMP 处理区域边界。三者协同的稳定性建立在对各自职责边界的清晰认识与对应工具链版本的充分验证上。
对开发者而言,多层防御落地的实际判断可以归纳为:HWASAN 的启用以平台与工具链支持为前提,CFI 应当成为生产构建的默认配置,PMP 的条目分配则需要按目标系统的实际威胁面排序。后续可展开的议题包括 CFI 与异常处理路径的协作细节,以及在异构集成场景下多层防御的跨核边界。

206

被折叠的 条评论
为什么被折叠?



