CVE-2022-2602 内核提权详细分析
字数 2979 2025-08-29 08:30:36

Linux内核漏洞CVE-2022-2602分析与利用教学文档

漏洞概述

漏洞编号: CVE-2022-2602
影响版本: Linux Kernel < v6.0.3
漏洞类型: Use-After-Free (UAF)
利用效果: 本地提权
漏洞模块: io_uring & unix_gc
漏洞本质: filp结构的UAF问题

环境搭建

复现环境:

  • QEMU虚拟机
  • Linux内核版本: v5.18.19

复现流程:

  1. 执行exp后会自动添加root用户
  2. 用户名: mowen
  3. 密码: mowen
  4. 使用su mowen完成提权

漏洞原理深度分析

核心机制

  1. io_uring文件注册机制:

    • io_uring_register系统调用中的IORING_REGISTER_FILES功能可以注册文件
    • 注册后文件会被放入io_uring->sk->receive_queue
    • 在Linux垃圾回收(GC)机制中会将这些文件取出并尝试释放
  2. 飞行计数机制:

    • Linux进程间通信(IPC)中用于传递文件描述符的引用计数机制
    • 防止文件在传输过程中被意外释放
    • 主要针对socket和io_uring等特殊文件类型
  3. 垃圾回收机制:

    • 解决socket文件自引用导致的资源无法释放问题
    • 通过unix_gc()函数实现
    • 遍历全局飞行列表gc_inflight_list进行资源回收

技术细节

飞行计数工作原理

  1. 正常文件传递流程:

    • 发送方: 文件引用计数+1 (防止接收前被关闭)
    • 接收方: 成功接收后引用计数-1
    • 如果接收前连接关闭: 通过sock_release调用fput()减少引用计数
  2. 自引用问题:

    • 当两个socket互相传递对方的fd时:
      • A发送给B,B发送给A
      • 引用计数都变为2
      • 关闭用户态fd后引用计数为1
      • 内核无法自动释放,形成资源泄漏

SCM_RIGHTS发送流程

  1. 发送准备阶段 (scm_send):

    • 获取file结构体
    • 初始化scm_cookie
    • 临时增加文件引用计数(通过fget_raw)
  2. 发送处理阶段 (unix_scm_to_skb):

    • scm_cookie添加到skb
    • 调用unix_attach_fds:
      • 通过scm_fp_dup增加文件引用计数(正式发送增加)
      • 通过unix_inflight增加飞行计数(仅对socket/io_uring)
  3. 发送完成阶段:

    • 将skb挂载到对端的sk_receive_queue
    • 调用scm_destroy释放临时增加的引用计数

垃圾回收机制(unix_gc)

  1. 触发条件: socket被关闭时调用

  2. 工作流程:

    • 遍历全局飞行列表gc_inflight_list
    • 检查文件引用计数 == 飞行计数的对象("垃圾"候选)
    • 将这些对象放入gc_candidates队列
    • 调用scan_children处理sk_receive_queue中的文件
    • 判断是否为真正的"闭环"引用
    • 释放符合条件的资源
  3. 关键函数:

    • scan_children: 处理sock->sk_receive_queue中的文件
    • __skb_queue_purge: 实际释放资源的函数

io_uring相关机制

  1. 文件注册流程 (io_sqe_files_register):

    • 调用io_sqe_files_scm
    • 使用get_file增加文件引用计数
    • 调用unix_inflight增加飞行计数(对socket/io_uring)
    • 将文件列表挂载到io_uring自己的sk_receive_queue
  2. 任务提交流程 (io_submit_sqe):

    • 初始化IO请求
    • 调用io_queue_sqe执行任务
    • 文件鉴权在io_write中的io_rw_init_file完成

漏洞利用分析

漏洞形成原因

  1. 非法释放流程:

    • io_uring注册文件时会将文件放入自己的sk_receive_queue
    • 垃圾回收时会错误地释放这些文件
    • 但后续任务仍会尝试使用已释放的文件结构体
  2. 关键问题:

    • io_uring自己的sk_receive_queue被垃圾回收机制误处理
    • 导致非socket文件被错误释放

完整利用流程

  1. 初始准备:

    • 创建socket pair: s[0]s[1] (引用计数=1)
    • 初始化io_uring: io_fd (引用计数=1)
    • 打开普通文件: file_fd (引用计数=1)
  2. 注册文件:

    • 使用io_uring_register注册s[1]file_fd
    • 结果:
      • s[1]: 引用计数=2, 飞行计数=1
      • file_fd: 引用计数=2
  3. 发送io_fd:

    • 通过s[0]发送io_fds[1]
    • io_fd: 引用计数=2, 飞行计数=1
  4. 关闭文件:

    • 关闭file_fd: 引用计数=1
    • 关闭s[0]: 被完全释放
    • 关闭s[1]: 引用计数=1, 飞行计数=1
  5. 制造阻塞:

    • 使用线程占用目标文件inode锁
    • 提交io_uring写任务(会被阻塞在实际写操作前)
  6. 触发漏洞:

    • 关闭io_uring(io_fd)
    • 触发垃圾回收:
      • 错误释放file_fd的文件结构体
      • 但写任务仍在等待
  7. 利用UAF:

    • 喷射大量"/etc/passwd"文件
    • 覆盖被释放的文件结构体
    • 当阻塞解除后,写入操作会修改"/etc/passwd"
  8. 提权完成:

    • 添加新的root用户
    • 通过su命令提权

防御措施

  1. 官方修复:

    • Linux内核v6.0.3已修复此漏洞
    • 主要修正垃圾回收机制对io_uring文件的处理逻辑
  2. 缓解措施:

    • 禁用io_uring功能(如非必需)
    • 使用内核模块黑名单阻止io_uring加载
    • 及时更新内核版本

参考资源

  1. [kernel exploit]CVE-2022-2602垃圾回收错误释放iouring的file导致UAF — bsauce
  2. [漏洞分析] CVE-2022-2602 内核提权详细分析
  3. io_uring, SCM_RIGHTS, and reference-count cycles (https://lwn.net/Articles/779472/)
  4. The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I) (https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html)

总结

CVE-2022-2602是一个典型的UAF漏洞,利用了Linux内核中io_uring模块与垃圾回收机制的交互问题。通过精心构造的文件引用关系,攻击者可以触发非法文件释放,进而实现权限提升。理解此漏洞需要深入掌握Linux内核的文件引用计数、飞行计数和垃圾回收机制,以及io_uring模块的工作原理。

Linux内核漏洞CVE-2022-2602分析与利用教学文档 漏洞概述 漏洞编号 : CVE-2022-2602 影响版本 : Linux Kernel < v6.0.3 漏洞类型 : Use-After-Free (UAF) 利用效果 : 本地提权 漏洞模块 : io_ uring & unix_ gc 漏洞本质 : filp结构的UAF问题 环境搭建 复现环境 : QEMU虚拟机 Linux内核版本: v5.18.19 复现流程 : 执行exp后会自动添加root用户 用户名: mowen 密码: mowen 使用 su mowen 完成提权 漏洞原理深度分析 核心机制 io_ uring文件注册机制 : io_uring_register 系统调用中的 IORING_REGISTER_FILES 功能可以注册文件 注册后文件会被放入 io_uring->sk->receive_queue 在Linux垃圾回收(GC)机制中会将这些文件取出并尝试释放 飞行计数机制 : Linux进程间通信(IPC)中用于传递文件描述符的引用计数机制 防止文件在传输过程中被意外释放 主要针对socket和io_ uring等特殊文件类型 垃圾回收机制 : 解决socket文件自引用导致的资源无法释放问题 通过 unix_gc() 函数实现 遍历全局飞行列表 gc_inflight_list 进行资源回收 技术细节 飞行计数工作原理 正常文件传递流程 : 发送方: 文件引用计数+1 (防止接收前被关闭) 接收方: 成功接收后引用计数-1 如果接收前连接关闭: 通过 sock_release 调用 fput() 减少引用计数 自引用问题 : 当两个socket互相传递对方的fd时: A发送给B,B发送给A 引用计数都变为2 关闭用户态fd后引用计数为1 内核无法自动释放,形成资源泄漏 SCM_ RIGHTS发送流程 发送准备阶段 ( scm_send ): 获取file结构体 初始化 scm_cookie 临时增加文件引用计数(通过 fget_raw ) 发送处理阶段 ( unix_scm_to_skb ): 将 scm_cookie 添加到skb 调用 unix_attach_fds : 通过 scm_fp_dup 增加文件引用计数(正式发送增加) 通过 unix_inflight 增加飞行计数(仅对socket/io_ uring) 发送完成阶段 : 将skb挂载到对端的 sk_receive_queue 调用 scm_destroy 释放临时增加的引用计数 垃圾回收机制( unix_gc ) 触发条件 : socket被关闭时调用 工作流程 : 遍历全局飞行列表 gc_inflight_list 检查文件引用计数 == 飞行计数的对象("垃圾"候选) 将这些对象放入 gc_candidates 队列 调用 scan_children 处理 sk_receive_queue 中的文件 判断是否为真正的"闭环"引用 释放符合条件的资源 关键函数 : scan_children : 处理 sock->sk_receive_queue 中的文件 __skb_queue_purge : 实际释放资源的函数 io_ uring相关机制 文件注册流程 ( io_sqe_files_register ): 调用 io_sqe_files_scm 使用 get_file 增加文件引用计数 调用 unix_inflight 增加飞行计数(对socket/io_ uring) 将文件列表挂载到 io_uring 自己的 sk_receive_queue 任务提交流程 ( io_submit_sqe ): 初始化IO请求 调用 io_queue_sqe 执行任务 文件鉴权在 io_write 中的 io_rw_init_file 完成 漏洞利用分析 漏洞形成原因 非法释放流程 : io_uring 注册文件时会将文件放入自己的 sk_receive_queue 垃圾回收时会错误地释放这些文件 但后续任务仍会尝试使用已释放的文件结构体 关键问题 : io_uring 自己的 sk_receive_queue 被垃圾回收机制误处理 导致非socket文件被错误释放 完整利用流程 初始准备 : 创建socket pair: s[0] 和 s[1] (引用计数=1) 初始化 io_uring : io_fd (引用计数=1) 打开普通文件: file_fd (引用计数=1) 注册文件 : 使用 io_uring_register 注册 s[1] 和 file_fd 结果: s[1] : 引用计数=2, 飞行计数=1 file_fd : 引用计数=2 发送io_ fd : 通过 s[0] 发送 io_fd 给 s[1] io_fd : 引用计数=2, 飞行计数=1 关闭文件 : 关闭 file_fd : 引用计数=1 关闭 s[0] : 被完全释放 关闭 s[1] : 引用计数=1, 飞行计数=1 制造阻塞 : 使用线程占用目标文件inode锁 提交 io_uring 写任务(会被阻塞在实际写操作前) 触发漏洞 : 关闭 io_uring ( io_fd ) 触发垃圾回收: 错误释放 file_fd 的文件结构体 但写任务仍在等待 利用UAF : 喷射大量"/etc/passwd"文件 覆盖被释放的文件结构体 当阻塞解除后,写入操作会修改"/etc/passwd" 提权完成 : 添加新的root用户 通过 su 命令提权 防御措施 官方修复 : Linux内核v6.0.3已修复此漏洞 主要修正垃圾回收机制对 io_uring 文件的处理逻辑 缓解措施 : 禁用 io_uring 功能(如非必需) 使用内核模块黑名单阻止 io_uring 加载 及时更新内核版本 参考资源 [ kernel exploit ]CVE-2022-2602垃圾回收错误释放iouring的file导致UAF — bsauce [ 漏洞分析 ] CVE-2022-2602 内核提权详细分析 io_ uring, SCM_ RIGHTS, and reference-count cycles (https://lwn.net/Articles/779472/) The quantum state of Linux kernel garbage collection CVE-2021-0920 (Part I) (https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html) 总结 CVE-2022-2602是一个典型的UAF漏洞,利用了Linux内核中 io_uring 模块与垃圾回收机制的交互问题。通过精心构造的文件引用关系,攻击者可以触发非法文件释放,进而实现权限提升。理解此漏洞需要深入掌握Linux内核的文件引用计数、飞行计数和垃圾回收机制,以及 io_uring 模块的工作原理。