reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
# 认证 RTOS 的隔离特性:SAFERTOS ESM / CMSIS-RTX5 安全特性
<CORE RULE>
这一族 RTOS 在"功能核 + 认证"之上,额外加了**访问控制与诊断特性**,会产生两类误判:
```
同一 VA:Task A 能访问、Task B 不能
→ 可能只是 per-task 区域/保护域策略
某 API 调用失败 / 某线程不运行
→ 可能只是调用方安全等级不够
```
**先在"谁能访问什么"这一层解释,再去怀疑对象损坏或逻辑错误。**
</CORE RULE>
## 一、SAFERTOS + Enhanced Security Module(ESM)
基础 SAFERTOS 的空间隔离目标是**非故意的内存访问**(损坏/编程错误);**ESM 把它加固到抵御"蓄意的"越权访问**。
| 机制 | 作用 |
|---|---|
| **访问控制策略(ACP)** | **限制每个任务可访问的 API 数量**(例如禁止某任务改自己的特权级、改访问权限、创建新资源);任务越受限,被攻陷后的攻击面越小 |
| **对象访问控制策略(OACP)** | **限制每个任务可访问的 RTOS 对象**(队列、信号量、事件组等),把任务约束在初始化时分配给它的对象上 |
| **间接对象 ID** | 把传统句柄(**本质是 C 指针**)换成**经交叉引用表解析的 Object ID**,使任务无法从句柄推出对象/TCB 的内存位置 |
| **per-task MPU/MMU 区域** | 每任务 3 或 5 个可配置区域(随处理器变体);**每次上下文切换都会重新编程**;默认非特权任务只能访问自己的栈 |
- 区域要求:**大小必须是 32 字节的倍数,基址必须 32 字节对齐**
- 可定义对所有任务可见的全局区域;**绝不应把另一个任务的栈分配给某任务**
- 区域在任务创建时配置(可读/可写/可执行、用户或特权),**运行期可以重新配置**
- ESM 还包括:数据混淆、安全的用户/内核空间分离层、任务上下文数据隔离(上下文存在 TCB 而不是栈上)、渗透检测监控
**RE 判据**:
```
句柄不是内存指针(间接对象 ID)
→ 别把句柄当 TCB/对象地址,也别指望从它推出结构布局
```
## 二、CMSIS-RTX5 的安全特性
在 `OS_SAFETY_FEATURES` 等开关下提供:
| 特性 | 含义 |
|---|---|
| **Safety Classes** | 低安全等级的线程**不能修改**高等级线程;提供线程类的查询/挂起/恢复等接口。**动机**:RTOS 对象是经"以数字 ID 为参数、在 handler 模式执行"的系统调用访问的,**单靠 MPU 保护可以被"用别的对象 ID 调 API"绕过**——安全等级给对象访问加了访问控制 |
| **MPU Protected Zones** | 空间隔离:一个 zone 是一组带访问权限的内存区/外设,分配给一个或多个线程;**zone ID 就是 MPU 表的行号**,上下文切换时内核比较 zone ID 并调用回调(用户实现,通常是把对应行载入 MPU);**内存违规触发 MemManage 异常**。注意:**中断处理程序绕过 MPU 保护**,因此必须以最高完整性等级验证 |
| **Thread Watchdog** | 时间隔离:安全等级线程声明期望的周期/响应时间并"喂狗",未达标时由监督线程升级处理(重启线程/重启应用/受控关停/硬件复位) |
| **对象指针检查** | 检查对象指针的**对齐与内存区域** |
| **SVC 函数指针检查** | 检查 SVC 函数指针的对齐与内存区域;**要求链接器划出专门的执行区**容纳 SVC veneer 输入段 |
**ISR FIFO 队列(延迟处理)**:
- **在 ISR 中调用部分 RTX API 不会立即完成**——请求先进入 **ISR FIFO 队列**,等 ISR 结束后由调度器处理
- 所以:
```
IRQ 中调用 osXxx()
→ 对象的实际状态在 IRQ 退出之后才变化
→ 完全正常
```
- **队列太小会产生 ISR 队列溢出错误**(专门的错误码),**此时系统状态已经不一致**;对策是**增大引起溢出的对象尺寸**,而不是怀疑队列对象损坏
- 另有"无效 SVC 函数"错误码(对象 ID 位置放的是函数)
## 三、权限模型与"拒绝"的语义
- SAFERTOS 的任务模型包含:自己的栈、**被许可的 MPU/MMU 区域**、**特权状态**、可访问的 RTOS 对象;**上下文切换时重新编程任务的存储区域**
- 因此三类现象都应先在权限层解释:
| 现象 | 优先解释 |
|---|---|
| 同一地址 Task A 能读、Task B fault | **per-task 区域配置**,不是内存损坏 |
| 普通任务不能访问某地址、**ISR 却能** | 用户任务与特权内核/ISR 上下文的权限本就不同 |
| API 调用附近出现特权转换 | 正常的 RTOS API 网关,**别当 ROP/trap 异常** |
**ESM 下"拒绝"的来源**:
- Task A 用某个句柄成功、Task B 用同一个句柄被拒 → 可能是**对象访问策略**拒绝,**不是句柄损坏**
- 句柄看起来完全不像指针 → ESM 用**间接/混淆的对象 ID** 取代直接指向控制块的句柄;应恢复 **ID → 查表 → 对象** 的路径,而不是硬套 `句柄 = 内核指针`
- **合法 API 返回拒绝** → 也可能是**访问控制策略**:当前任务根本没有调用该 API 的权限,而不是 API 实现坏了
## 决策树
```
拿到 SAFERTOS / RTX5 一类认证 RTOS 目标
├─ 同一地址的访问权限不一致
│ ├─ 查 per-task 区域配置(SAFERTOS)或 MPU zone 归属(RTX5)
│ └─ 区域可能被运行期重新配置
├─ 句柄看起来不像指针 / 指向奇怪的地方
│ └─ SAFERTOS ESM 用的是间接对象 ID + 交叉引用表
├─ 某 API 调用被拒
│ ├─ 查调用方的访问控制策略(能否调这个 API)与对象访问策略(能否用这个对象)
│ └─ RTX5 下查调用线程的安全等级
├─ ISR 里调用的 API 没立即生效
│ ├─ 请求进了 ISR FIFO,ISR 退出后才处理
│ └─ 出现队列溢出错误 → 增大对象尺寸,且此时系统已不一致
└─ 出现内存管理异常
├─ RTX5:MPU zone 违规
└─ 注意中断处理程序绕过 MPU 保护
```
## 工具与验证
- 访问控制:ACP/OACP 配置与运行期检查点(SAFERTOS);安全等级与对象属性(RTX5)
- 空间:per-task 区域/zone 表、区域对齐与大小约束、运行期重配置调用
- 延迟处理:ISR FIFO 队列的容量与溢出错误码
- 验证:能同时说清「这次访问受哪条策略约束 + 区域/等级当前是什么 + 失败是策略拒绝还是真的坏了」
## 该平台的坑(汇总)
- **把 per-task 区域导致的访问失败当内存损坏**:权限差异可能完全合法
- **假设区域在任务生命周期内不变**:运行期可以重新配置
- **把 SAFERTOS 的句柄当内存指针**:ESM 下是经交叉引用表解析的间接对象 ID
- **忘了区域的大小/对齐约束**:必须 32 字节倍数且基址 32 字节对齐
- **以为 MPU 保护覆盖中断处理程序**:中断绕过保护,必须单独验证
- **只在 MPU 层找越权防线**:RTX5 明确说单靠 MPU 可被"用别的对象 ID 调 API"绕过,需要安全等级
- **把 ISR 中调用的 API 未立即生效当 bug**:请求进 ISR FIFO,退出后才处理
- **把 ISR 队列溢出当队列对象损坏**:是容量不足,且此时系统状态已不一致
- **忽略 SVC 函数指针检查对链接布局的要求**:需要专门的执行区容纳 veneer