Linux kernel exploit:CVE-2022-29582
字数 1898 2025-08-05 11:39:48

Linux内核漏洞CVE-2022-29582分析与利用

漏洞概述

CVE-2022-29582是Linux内核io_uring子系统中的一个本地提权漏洞,影响版本从v5.10到v5.12的主线版本,5.10.109修复了此漏洞。漏洞评分7.0,属于条件竞争漏洞,涉及IORING_OP_TIMEOUT和IORING_OP_LINK_TIMEOUT操作。

漏洞环境

  • 测试版本:Linux 5.10.90
  • 关键编译选项:
    CONFIG_E1000=y
    CONFIG_E1000E=y
    CONFIG_BINFMT_MISC=y
    CONFIG_TLS=y
    CONFIG_TLS_DEVICE=y
    CONFIG_TLS_TOE=y
    

补丁分析

补丁主要修改了io_flush_timeouts函数,使用list_for_each_entry_safe替代了原来的list_emptylist_first_entry组合,并移除了list_del_init调用。

io_uring基础

io_uring是Linux内核提供的高性能、低延迟I/O处理机制,主要组件:

  1. 提交队列(Submission Queue, SQ):存放I/O操作请求
  2. 完成队列(Completion Queue, CQ):存放已完成操作的结果
  3. 提交队列条目(SQE):编码单个I/O操作的结构体

关键结构体io_uring_sqe中,opcode字段指定I/O请求类型,如读取、写入、超时等。

Linked SQEs

通过设置SQE的flags字段中的IOSQE_IO_LINK标志,可以将多个SQE链接起来形成链。链中的操作按顺序执行,若链中任何操作失败,整个链都会失败。

超时操作

IORING_OP_TIMEOUT

设置超时时间T和可选完成事件计数C:

  • 当超时时间T过去时:hrtimer启动,请求被取消并返回-ETIME
  • 当完成事件计数C的其他请求已完成时:超时成功

IORING_OP_LINK_TIMEOUT

为特定操作设置超时:

  • 如果超时时间过去:取消原始操作
  • 如果原始操作已完成:取消超时操作

漏洞原理

漏洞源于将IORING_OP_TIMEOUT和IORING_OP_LINK_TIMEOUT操作放在同一链上时可能出现的竞争条件:

  1. 当T被销毁时,它保留了一个悬空引用指向LT
  2. 如果LT在T被销毁前被释放,会出现Use-After-Free情况
  3. 通过精心构造,可以将此UAF转化为提权漏洞

漏洞利用步骤

1. 替换LT对象

目标是用另一个对象LT'替换被释放的LT对象。由于堆隔离限制,LT'只能是另一个struct io_kiocb对象。

选择IORING_OP_TEE类型请求作为LT',因为:

  • 可以通过do_tee()从管道端读取来无限期阻塞
  • 需要时可通过写入管道另一端恢复执行

2. 释放文件对象

通过精心构造虚假的文件对象,绕过filp_close()中的检查:

  • 设置引用计数为1
  • 设置f_mode为FMODE_PATH
  • 设置f_op指向特定地址使f_op->flush为NULL

3. 跨缓存攻击

由于文件对象有自己的专用缓存(filp),需要通过以下步骤将页面释放回页面分配器:

  1. 填满缓存中正在使用的所有页面
  2. 释放目标页面上的所有对象
  3. 触发unfreeze_partials()将空页面释放回页面分配器

4. 页面重新分配

将释放的页面重新分配到kmalloc-512缓存,使用msg_msgseg对象覆盖文件对象。

5. 信息泄露

通过喷射tls_context对象并读取其内容来获取内核地址:

  • tls_context中的list_head指向自身
  • sk_proto指向tcp_prot,可用于计算内核基址

6. 代码执行

  1. 准备伪造的tls_context数据:

    • 包含ROP链
    • 覆盖sk_prototls_context地址
    • 覆盖getsockopt()为栈旋转gadget地址
  2. 触发执行:

    • 调用getsockopt()触发栈迁移
    • ROP链开始执行,完成提权

参考链接

  1. CVE-2022-29582
  2. 利用poll_list对象构造kmalloc-32任意释放
  3. slub内存管理分析

利用代码

原作者提供的利用代码可从以下链接获取:
下载链接

登录用户名: hi
密码: lol

总结

CVE-2022-29582是一个复杂的条件竞争漏洞,涉及io_uring子系统的超时处理机制。通过精心构造的竞争条件和多阶段的堆操作,攻击者可以将此漏洞转化为可靠的提权漏洞。防御此类漏洞需要及时更新内核版本,并考虑使用更安全的编程模式来处理异步操作和资源释放。

Linux内核漏洞CVE-2022-29582分析与利用 漏洞概述 CVE-2022-29582是Linux内核io_ uring子系统中的一个本地提权漏洞,影响版本从v5.10到v5.12的主线版本,5.10.109修复了此漏洞。漏洞评分7.0,属于条件竞争漏洞,涉及IORING_ OP_ TIMEOUT和IORING_ OP_ LINK_ TIMEOUT操作。 漏洞环境 测试版本:Linux 5.10.90 关键编译选项: 补丁分析 补丁主要修改了 io_flush_timeouts 函数,使用 list_for_each_entry_safe 替代了原来的 list_empty 和 list_first_entry 组合,并移除了 list_del_init 调用。 io_ uring基础 io_ uring是Linux内核提供的高性能、低延迟I/O处理机制,主要组件: 提交队列(Submission Queue, SQ) :存放I/O操作请求 完成队列(Completion Queue, CQ) :存放已完成操作的结果 提交队列条目(SQE) :编码单个I/O操作的结构体 关键结构体 io_uring_sqe 中, opcode 字段指定I/O请求类型,如读取、写入、超时等。 Linked SQEs 通过设置SQE的 flags 字段中的 IOSQE_IO_LINK 标志,可以将多个SQE链接起来形成链。链中的操作按顺序执行,若链中任何操作失败,整个链都会失败。 超时操作 IORING_ OP_ TIMEOUT 设置超时时间T和可选完成事件计数C: 当超时时间T过去时:hrtimer启动,请求被取消并返回-ETIME 当完成事件计数C的其他请求已完成时:超时成功 IORING_ OP_ LINK_ TIMEOUT 为特定操作设置超时: 如果超时时间过去:取消原始操作 如果原始操作已完成:取消超时操作 漏洞原理 漏洞源于将IORING_ OP_ TIMEOUT和IORING_ OP_ LINK_ TIMEOUT操作放在同一链上时可能出现的竞争条件: 当T被销毁时,它保留了一个悬空引用指向LT 如果LT在T被销毁前被释放,会出现Use-After-Free情况 通过精心构造,可以将此UAF转化为提权漏洞 漏洞利用步骤 1. 替换LT对象 目标是用另一个对象LT'替换被释放的LT对象。由于堆隔离限制,LT'只能是另一个 struct io_kiocb 对象。 选择IORING_ OP_ TEE类型请求作为LT',因为: 可以通过 do_tee() 从管道端读取来无限期阻塞 需要时可通过写入管道另一端恢复执行 2. 释放文件对象 通过精心构造虚假的文件对象,绕过 filp_close() 中的检查: 设置引用计数为1 设置 f_mode 为FMODE_ PATH 设置 f_op 指向特定地址使 f_op->flush 为NULL 3. 跨缓存攻击 由于文件对象有自己的专用缓存(filp),需要通过以下步骤将页面释放回页面分配器: 填满缓存中正在使用的所有页面 释放目标页面上的所有对象 触发 unfreeze_partials() 将空页面释放回页面分配器 4. 页面重新分配 将释放的页面重新分配到kmalloc-512缓存,使用 msg_msgseg 对象覆盖文件对象。 5. 信息泄露 通过喷射 tls_context 对象并读取其内容来获取内核地址: tls_context 中的 list_head 指向自身 sk_proto 指向 tcp_prot ,可用于计算内核基址 6. 代码执行 准备伪造的 tls_context 数据: 包含ROP链 覆盖 sk_proto 为 tls_context 地址 覆盖 getsockopt() 为栈旋转gadget地址 触发执行: 调用 getsockopt() 触发栈迁移 ROP链开始执行,完成提权 参考链接 CVE-2022-29582 利用poll_ list对象构造kmalloc-32任意释放 slub内存管理分析 利用代码 原作者提供的利用代码可从以下链接获取: 下载链接 登录用户名: hi 密码: lol 总结 CVE-2022-29582是一个复杂的条件竞争漏洞,涉及io_ uring子系统的超时处理机制。通过精心构造的竞争条件和多阶段的堆操作,攻击者可以将此漏洞转化为可靠的提权漏洞。防御此类漏洞需要及时更新内核版本,并考虑使用更安全的编程模式来处理异步操作和资源释放。