io_uring UAF:Linux 内核异步 I/O 子系统释放后重用提权漏洞(CVE-2022-2602)
文档版本:v1.0 · 更新日期:2026-05-18 适用对象:安全研究员、系统管理员、DevSecOps 团队
漏洞速览
| 属性 | 详情 |
|---|---|
| CVE 编号 | CVE-2022-2602 |
| 漏洞别名 | io_uring UAF / DirtyCred |
| CVSS 评分 | 7.8(HIGH) |
| CVSS 向量 | AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 漏洞类型 | CWE-416:释放后重用(Use-After-Free) |
| 攻击向量 | 本地(Local) |
| 权限要求 | 低权限(Low) |
| 用户交互 | 不需要(None) |
| 公开日期 | 2022-10-18 |
| PoC 状态 | 已公开 |
| 补丁版本 | Linux Kernel >= 6.1-rc1 |
| 临时缓解 | 可禁用 io_uring 或限制非特权用户访问 |
关键时间线
2022-10-18 ── oss-security 邮件列表公开披露漏洞详情
2022-12-06 ── Linux 主线合并修复补丁(包含在 6.1-rc1 合并窗口中)
2022-12-11 ── 稳定版内核 6.1 发布,正式修复
2022-12-21 ── 详细技术分析与 EXP 公开(DirtyCred 文件利用技术)
2023-01-20 ── 各发行版完成 backport 修复发布
漏洞简介
io_uring 是 Linux 内核自 5.1 版本引入的高性能异步 I/O 子系统。它允许用户态程序通过共享内存环形缓冲区(Ring Buffer)向内核提交 I/O 操作请求,内核异步完成后将结果写入完成队列(Completion Queue),大幅减少了系统调用开销和上下文切换。io_uring 被广泛应用于高性能网络服务、数据库(如 ScyllaDB)、存储引擎等场景。
CVE-2022-2602 位于 io_uring 的 IORING_REGISTER_FILES 功能中,涉及文件描述符(file 结构体)的生命周期管理错误。当攻击者通过 io_uring_register() 注册文件描述符后,利用 unix_gc(Unix 域套接字垃圾回收)机制触发已注册文件的异常释放,导致 io_uring 内部仍然持有指向已释放 file 结构体的悬空指针(Dangling Pointer)。随后对该指针的引用即构成 Use-After-Free,攻击者可通过堆喷(Heap Spray)技术控制释放后的内存区域,实现内核任意代码执行。
该漏洞的特别之处在于:它不仅是 io_uring 子系统自身的问题,还涉及了 Unix 域套接字的 垃圾回收(GC)路径与 io_uring 文件注册路径之间的非预期交互,展现了内核子系统间耦合带来的安全隐患。
技术原理
利用链概述
低权限进程
│
├── ① 创建 io_uring 实例(io_uring_setup)
│
├── ② 创建 Unix 域套接字对,将一端注册到 io_uring
│ io_uring_register(IORING_REGISTER_FILES, fds_array)
│
├── ③ 操纵套接字形成引用循环,触发 unix_gc
│ Unix 域套接字的垃圾回收器错误释放已注册的 file 结构体
│
├── ④ io_uring 仍持有悬空指针 → UAF
│
├── ⑤ 通过堆喷控制释放后的内存区域
│ 植入精心构造的伪造 file 结构体(f_op 指向攻击者控制区)
│
└── ⑥ 触发 io_uring 操作 → 内核代码执行 → 提权至 root
详细步骤
步骤一:io_uring 文件注册
io_uring 提供了 IORING_REGISTER_FILES 操作,允许用户预注册一组文件描述符。这使得后续 I/O 操作可以通过固定索引引用文件,减少每次 fget() 调用的开销。
int ring_fd = io_uring_setup(entries, ¶ms); // 创建 io_uring 实例
int fds[] = {socket_fd};
io_uring_register(ring_fd, IORING_REGISTER_FILES, fds, 1);注册后,io_uring 内部通过 io_uring->registered_files[] 数组持有 file 结构的引用计数。正常情况下,即使用户态 close() 文件描述符,注册的文件也不会被释放。
步骤二:Unix 域套接字 GC 异常释放
攻击者构造 Unix 域套接字之间的引用循环(如通过 SCM_RIGHTS 传递文件描述符),然后打破循环触发内核的 unix_gc(垃圾回收)。unix_gc 在特定条件下会错误地将已注册到 io_uring 的 file 结构体释放,而未检查其是否仍被 io_uring 引用。
攻击者控制的套接字拓扑:
skA ──── SCM_RIGHTS(skB) ────> skB
↑ │
└──── SCM_RIGHTS(skA) ────────────┘
形成循环 → 触发 unix_gc → 释放已注册 file
步骤三:UAF 触发
释放发生后,io_uring 的 registered_files[] 中仍保留指向已释放内存的指针。当攻击者通过 io_uring 操作(如 IORING_OP_READ)引用该索引时,内核访问已释放的 file 结构体:
// 内核代码简化示意
struct file *file = io_uring->registered_files[index]; // 悬空指针!
if (file) {
file->f_op->read(file, buf, count, &pos); // UAF 引用!
}步骤四:堆喷占位与内核 RCE
攻击者通过内核堆喷(如使用 msg_msg 消息队列、sk_buff 网络缓冲区或其他内核对象分配器)精确占据释放后的内存区域。通过精心构造数据,覆盖 file->f_op 函数指针表,使其指向攻击者控制的 ROP 链或内核 shellcode:
// 伪造的 file 结构体布局
struct fake_file {
// ... 填充合法值通过检查 ...
struct file_operations *f_op = &fake_fops; // 指向攻击者控制的函数表
};
struct fake_file_operations {
ssize_t (*read)() = rop_chain; // 触发 read → 执行 ROP
ssize_t (*write)() = rop_chain; // 触发 write → 执行 ROP
// ...
};当后续 io_uring_enter() 触发 I/O 操作时,内核调用被劫持的函数指针,攻击者获得内核态任意代码执行能力,最终通过 commit_creds(prepare_kernel_cred(0)) 将当前进程权限提升至 root。
关键技术点
| 组件 | 作用 |
|---|---|
io_uring_register() | 注册文件描述符到 io_uring,内部持有 file 引用 |
| unix_gc | Unix 域套接字垃圾回收,错误释放已注册文件 |
struct file | 内核中的文件对象,包含 f_op 函数指针表 |
file_operations | 文件操作的虚函数表,UAF 后劫持的跳板 |
| 内核堆喷(Heap Spray) | 通过分配特定内核对象占位,控制释放后的内存内容 |
受影响版本
| 组件 | 受影响版本 | 安全版本 | 备注 |
|---|---|---|---|
| Linux Kernel(主线) | 5.1 ~ 6.0.x | >= 6.1 | io_uring 自 5.1 引入,修复在 6.1-rc1 |
| Linux Kernel(5.15 LTS) | 5.15.0 ~ 5.15.x | backport 修复版本(发行版跟进) | — |
| Linux Kernel(5.10 LTS) | 5.10.0 ~ 5.10.x(如启用 io_uring) | backport 修复版本 | 部分发行版默认未开启 |
| Ubuntu 22.04 | kernel >= 5.15 | 发行版已 backport | 检查 USN 公告 |
| Debian 11(Bullseye) | kernel 5.10+ | 发行版已 backport | — |
| RHEL 9 / AlmaLinux 9 | kernel 5.14+ | 发行版已 backport | — |
| CentOS / RHEL 7/8 | 默认内核 < 5.1 | N/A | 不受影响(io_uring 未引入或默认禁用) |
| 内核 < 5.1 | N/A | N/A | 不受影响(io_uring 子系统不存在) |
漏洞影响场景
场景 1:本地低权限用户提权
- 前提条件:运行受影响内核,
io_uring可用且非特权用户可创建 io_uring 实例(kernel.io_uring_disabled=0) - 攻击过程:编译执行公开 EXP,利用 UAF 劫持内核执行流
- 最坏影响:获取 root 权限
场景 2:容器逃逸
- 前提条件:容器内 io_uring 未被 seccomp 拦截,宿主机内核受影响
- 攻击过程:在容器内运行 io_uring UAF EXP,利用内核漏洞获取宿主机 root
- 最坏影响:突破容器隔离,攻击宿主机及其他容器
场景 3:云环境 / Kubernetes 集群
- 前提条件:Worker Node 运行受影响内核,Pod SecurityContext 未限制 io_uring
- 攻击过程:恶意 Pod 使用 io_uring 执行提权攻击
- 最坏影响:Node 级别沦陷,访问 etcd 密钥、Secrets、横向移动
场景 4:高性能计算 / 数据库服务器
- 前提条件:HPC 集群或数据库节点运行受影响内核
- 攻击过程:共享环境中低权限用户利用漏洞提权
- 最坏影响:窃取科研数据、破坏计算任务完整性
修复措施
推荐修复(根本解决)
升级内核至 6.1 或发行版 backport 修复版本。
# Ubuntu / Debian
sudo apt update && sudo apt upgrade -y linux-image-generic
sudo reboot
# RHEL 9 / AlmaLinux 9
sudo dnf update kernel -y
sudo reboot
# Fedora
sudo dnf update kernel -y
sudo reboot
# 验证
uname -r
# 期望:>= 6.1 或发行版修复版本(检查对应安全公告)临时缓解(无法立即升级时)
方案一:禁用 io_uring(推荐)
# 运行时禁用(立即生效,重启后失效)
sudo sysctl -w kernel.io_uring_disabled=2
# 持久化禁用
echo "kernel.io_uring_disabled=2" | sudo tee -a /etc/sysctl.d/99-disable-io_uring.conf
sudo sysctl -p /etc/sysctl.d/99-disable-io_uring.confkernel.io_uring_disabled 值含义:
0:所有进程均可创建 io_uring(默认)1:仅CAP_SYS_ADMIN进程可创建2:完全禁用 io_uring
| 副作用 | 说明 |
|---|---|
| 影响高性能应用 | 依赖 io_uring 的应用(ScyllaDB、某些存储引擎)将无法正常工作 |
| 不支持即时恢复 | 禁用后已运行的 io_uring 实例不受影响,需重启服务 |
方案二:Seccomp 限制(容器环境)
# Kubernetes Pod SecurityContext 示例
securityContext:
seccompProfile:
type: RuntimeDefault在容器中,使用 seccomp profile 拦截 io_uring_setup 系统调用(syscall 425)。
一键检查与执行临时修复脚本
检查脚本
#!/bin/bash
# io_uring UAF (CVE-2022-2602) 漏洞检查脚本
# 用途:检查系统是否可能受 io_uring UAF 漏洞影响
# 限制:基于内核版本和 io_uring 状态判断
echo "=== io_uring UAF (CVE-2022-2602) 漏洞检查 ==="
echo ""
KERNEL_VER=$(uname -r | cut -d'-' -f1)
echo "当前内核版本:$(uname -r)"
MAJOR=$(echo "$KERNEL_VER" | cut -d'.' -f1)
MINOR=$(echo "$KERNEL_VER" | cut -d'.' -f2)
echo ""
# 检测 io_uring 状态
IO_URING_DISABLED=$(sysctl -n kernel.io_uring_disabled 2>/dev/null)
if [ -z "$IO_URING_DISABLED" ]; then
IO_URING_DISABLED=0
fi
echo "io_uring 状态:"
case $IO_URING_DISABLED in
0) echo " → 所有进程可用(⚠️ 风险最高)" ;;
1) echo " → 仅 CAP_SYS_ADMIN 可用(风险降低)" ;;
2) echo " → 已完全禁用(✅ 不受影响)" ;;
esac
echo ""
# 版本判断
if [ "$MAJOR" -lt 5 ]; then
echo "✅ 内核 < 5.1,io_uring 不存在,不受影响"
elif [ "$MAJOR" -ge 7 ]; then
echo "✅ 内核 >= 7.0,假定已修复(请验证发行版公告)"
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -ge 1 ]; then
echo "✅ 内核 >= 6.1,主线已修复"
elif [ "$IO_URING_DISABLED" -ge 2 ]; then
echo "✅ io_uring 已禁用,不受此漏洞影响"
else
echo "⚠️ 当前系统可能受 io_uring UAF (CVE-2022-2602) 影响"
echo " 建议:升级内核至 6.1+ 或禁用 io_uring"
fi
# 确认 io_uring 模块是否加载
if lsmod 2>/dev/null | grep -q io_uring; then
echo ""
echo "⚠️ io_uring 内核模块已加载"
fi
echo ""
echo "=== 检查完成 ==="临时修复脚本
#!/bin/bash
# io_uring UAF (CVE-2022-2602) 临时修复脚本
# 用途:通过 sysctl 禁用 io_uring 子系统
# 注意:此操作可能影响依赖 io_uring 的应用程序
set -e
echo "=== io_uring UAF (CVE-2022-2602) 临时修复 ==="
echo ""
# 备份当前配置
CURRENT_VALUE=$(sysctl -n kernel.io_uring_disabled 2>/dev/null || echo 0)
echo "当前 kernel.io_uring_disabled = $CURRENT_VALUE"
echo "备份当前值到 /etc/sysctl.d/99-io_uring-backup.conf"
echo "kernel.io_uring_disabled=$CURRENT_VALUE" | sudo tee /etc/sysctl.d/99-io_uring-backup.conf > /dev/null
# 完全禁用 io_uring
echo "正在禁用 io_uring..."
sudo sysctl -w kernel.io_uring_disabled=2
# 持久化
echo "kernel.io_uring_disabled=2" | sudo tee /etc/sysctl.d/99-disable-io_uring.conf > /dev/null
sudo sysctl -p /etc/sysctl.d/99-disable-io_uring.conf
echo ""
echo "✅ io_uring 已禁用(立即生效 + 重启后保持)"
echo ""
echo "如需回滚,执行:"
echo " sudo rm /etc/sysctl.d/99-disable-io_uring.conf"
echo " sudo cp /etc/sysctl.d/99-io_uring-backup.conf /etc/sysctl.d/99-restore-io_uring.conf"
echo " sudo sysctl -p /etc/sysctl.d/99-restore-io_uring.conf"参考资源
官方与 NVD
| 标题 | URL | 类型标签 |
|---|---|---|
| NVD - CVE-2022-2602 | https://nvd.nist.gov/vuln/detail/CVE-2022-2602 | NVD |
| oss-security 披露帖 | https://www.openwall.com/lists/oss-security/2022/10/18/4 | 官方 |
| MITRE CVE-2022-2602 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-2602 | 官方 |
技术分析
| 标题 | URL | 类型标签 |
|---|---|---|
| DirtyCred: File Exploitation on io_uring UAF | https://blog.hacktivesecurity.com/index.php/2022/12/21/cve-2022-2602-dirtycred-file-exploitation-applied-on-an-io_uring-uaf/ | 技术分析 |
| CSDN 内核 exploit 分析:CVE-2022-2602 | https://blog.csdn.net/panhewu9919/article/list/1 | 技术分析/PoC |
| Red Hat CVE 页面 | https://access.redhat.com/security/cve/cve-2022-2602 | 厂商公告 |
| Ubuntu Security Notice | https://ubuntu.com/security/CVE-2022-2602 | 厂商公告 |
PoC 与工具
| 标题 | URL | 类型标签 |
|---|---|---|
| CVE-2022-2602 PoC(GitHub) | https://github.com/nickfoconnor/CVE-2022-2602-LPE [待验证] | PoC |
io_uring 的高性能以复杂的生命周期管理为代价。CVE-2022-2602 揭示了内核子系统间(io_uring + Unix GC)非预期交互的危险性——一个子系统的垃圾回收逻辑错误,可能被另一个子系统的垂悬引用放大为内核代码执行。