CVE-2024-0582 内核提权详细分析
字数 2221 2025-08-29 08:30:13

CVE-2024-0582 Linux内核提权漏洞分析与利用指南

漏洞概述

漏洞编号: CVE-2024-0582
影响版本: Linux Kernel v6.4 至 v6.6.5
漏洞类型: Use-After-Free (UAF)
漏洞组件: io_uring子系统中的io_unregister_pbuf_ring功能
利用效果: 本地提权
CVSS评分: 待评估(根据描述可能为高危)

漏洞背景

自Linux内核5.7版本起,io_uring引入了缓冲区池管理功能,允许应用程序注册由组ID标识的缓冲区池。从6.4版本开始,进一步允许将缓冲区环的分配委托给内核(通过IOU_PBUF_RING_MMAP标识符)。这一改进在实现上存在引用计数管理缺陷,导致了UAF漏洞。

漏洞原理

漏洞本质是引用计数管理不当导致的Use-After-Free问题:

  1. 当使用IOU_PBUF_RING_MMAP标识符时,内核会分配缓冲区环空间并通过mmap映射到用户空间
  2. 此过程不会修改页面结构(page)的引用计数
  3. 当调用io_unregister_pbuf_ring()释放空间时,会调用put_page_testzero(page)对page引用减1
  4. 由于mmap映射时没有增加引用计数,内核无法正确判断内存是否仍被映射
  5. 导致用户空间仍持有有效映射的情况下,内核已释放了对应的物理页面

漏洞详细分析

io_register_pbuf_ring流程

  1. 参数检查:

    • 将用户数据复制到内核reg结构
    • 检查entries是否为2的幂次方
    • 限制entries最大不超过65536(实际最大32768)
  2. 缓冲区列表管理:

    • 如果ctx->io_bl未初始化,则初始化ctx->io_bl(64长度的io_buffer_list数组)
    • 当ID≥64时,使用xarray管理
  3. 缓冲区分配:

    • 调用io_buffer_get_list()获取对应ID的io_buffer_list(bl)
    • 使用IOU_PBUF_RING_MMAP时,调用io_alloc_pbuf_ring()分配buf_ring空间
    • 否则由用户提供内存页

io_alloc_pbuf_ring关键点

  • 为io_uring_buf_ring申请空间
  • buf_ring环存放ring_entries个io_uring_buf_ring结构
  • 申请pages为复合页(compound page)

io_unregister_pbuf_ring流程

  1. 根据ID获取io_buffer_list
  2. 对于ID<64的情况:
    • 调用__io_remove_buffers仅释放bl->buf_ring
  3. 对于ID≥64的情况:
    • 直接释放整个bl结构

__io_remove_buffers关键缺陷

  • 获取bl->buf_ring的虚拟地址
  • 调用put_page_testzero()对page引用减1
  • 若引用==0则释放page
  • 问题: mmap映射持有时不会改变page引用,内核无法感知映射状态

漏洞利用技术

利用思路

  1. 篡改filp->f_mode为可写
  2. 修改/etc/passwd文件添加特权用户

详细利用步骤

  1. 初始化阶段:

    • 绑定CPU核心
    • 注册io_uring实例
    • 设置最大可打开文件数(将rlim_cur设置为rlim_max)
    • 记录nr_files(最大打开文件数量)
  2. 注册缓冲区环:

    • 使用IOU_PBUF_RING_MMAP注册指定ID的buf_ring区域
    • 通过mmap将内核分配的缓冲区映射到用户空间
  3. 释放缓冲区环:

    • 调用io_uring_unregister_buf_ring释放所有buf_ring
    • 此时内核已释放内存但用户空间仍持有映射
  4. 文件喷射:

    • 打开nr_files个/etc/passwd文件(使用O_RDONLY标志)
    • 这些文件的f_mode固定为0x494a801d
  5. UAF利用:

    • 通过固定的f_flags+f_mode模式(0x484a801d00008000)定位目标文件结构
    • 修改f_mode使其具有写权限
  6. 写入操作:

    • 由于不知道具体文件描述符,暴力尝试对所有打开的/etc/passwd进行写操作
    • 通过返回值判断是否写入成功

防御与缓解措施

  1. 官方补丁:

    • 升级到Linux Kernel v6.6.5或更高版本
    • 补丁应正确处理mmap映射时的页面引用计数
  2. 临时缓解:

    • 禁用io_uring功能(如非必要)
    • 限制非特权用户使用io_uring
  3. 系统加固:

    • 启用内核地址空间布局随机化(KASLR)
    • 使用SELinux/AppArmor限制特权操作

复现环境

  • 内核版本: Linux Kernel v6.5.3
  • 虚拟化环境: QEMU
  • 测试账号: hacker(通过漏洞添加的root用户)

结论

CVE-2024-0582是一个典型的引用计数管理不当导致的内核UAF漏洞,通过精心构造的利用链可以实现本地提权。该漏洞展示了内核子系统间交互时资源管理的重要性,特别是在涉及用户空间映射的场景下。系统管理员应及时应用补丁,开发者应引以为戒,在类似功能实现中严格管理资源生命周期。

CVE-2024-0582 Linux内核提权漏洞分析与利用指南 漏洞概述 漏洞编号 : CVE-2024-0582 影响版本 : Linux Kernel v6.4 至 v6.6.5 漏洞类型 : Use-After-Free (UAF) 漏洞组件 : io_ uring子系统中的io_ unregister_ pbuf_ ring功能 利用效果 : 本地提权 CVSS评分 : 待评估(根据描述可能为高危) 漏洞背景 自Linux内核5.7版本起,io_ uring引入了缓冲区池管理功能,允许应用程序注册由组ID标识的缓冲区池。从6.4版本开始,进一步允许将缓冲区环的分配委托给内核(通过IOU_ PBUF_ RING_ MMAP标识符)。这一改进在实现上存在引用计数管理缺陷,导致了UAF漏洞。 漏洞原理 漏洞本质是引用计数管理不当导致的Use-After-Free问题: 当使用IOU_ PBUF_ RING_ MMAP标识符时,内核会分配缓冲区环空间并通过mmap映射到用户空间 此过程 不会修改页面结构(page)的引用计数 当调用io_ unregister_ pbuf_ ring()释放空间时,会调用put_ page_ testzero(page)对page引用减1 由于mmap映射时没有增加引用计数,内核无法正确判断内存是否仍被映射 导致用户空间仍持有有效映射的情况下,内核已释放了对应的物理页面 漏洞详细分析 io_ register_ pbuf_ ring流程 参数检查 : 将用户数据复制到内核reg结构 检查entries是否为2的幂次方 限制entries最大不超过65536(实际最大32768) 缓冲区列表管理 : 如果ctx->io_ bl未初始化,则初始化ctx->io_ bl(64长度的io_ buffer_ list数组) 当ID≥64时,使用xarray管理 缓冲区分配 : 调用io_ buffer_ get_ list()获取对应ID的io_ buffer_ list(bl) 使用IOU_ PBUF_ RING_ MMAP时,调用io_ alloc_ pbuf_ ring()分配buf_ ring空间 否则由用户提供内存页 io_ alloc_ pbuf_ ring关键点 为io_ uring_ buf_ ring申请空间 buf_ ring环存放ring_ entries个io_ uring_ buf_ ring结构 申请pages为复合页(compound page) io_ unregister_ pbuf_ ring流程 根据ID获取io_ buffer_ list 对于ID <64的情况: 调用__ io_ remove_ buffers仅释放bl->buf_ ring 对于ID≥64的情况: 直接释放整个bl结构 __ io_ remove_ buffers关键缺陷 获取bl->buf_ ring的虚拟地址 调用put_ page_ testzero()对page引用减1 若引用==0则释放page 问题 : mmap映射持有时不会改变page引用,内核无法感知映射状态 漏洞利用技术 利用思路 篡改filp->f_ mode为可写 修改/etc/passwd文件添加特权用户 详细利用步骤 初始化阶段 : 绑定CPU核心 注册io_ uring实例 设置最大可打开文件数(将rlim_ cur设置为rlim_ max) 记录nr_ files(最大打开文件数量) 注册缓冲区环 : 使用IOU_ PBUF_ RING_ MMAP注册指定ID的buf_ ring区域 通过mmap将内核分配的缓冲区映射到用户空间 释放缓冲区环 : 调用io_ uring_ unregister_ buf_ ring释放所有buf_ ring 此时内核已释放内存但用户空间仍持有映射 文件喷射 : 打开nr_ files个/etc/passwd文件(使用O_ RDONLY标志) 这些文件的f_ mode固定为0x494a801d UAF利用 : 通过固定的f_ flags+f_ mode模式(0x484a801d00008000)定位目标文件结构 修改f_ mode使其具有写权限 写入操作 : 由于不知道具体文件描述符,暴力尝试对所有打开的/etc/passwd进行写操作 通过返回值判断是否写入成功 防御与缓解措施 官方补丁 : 升级到Linux Kernel v6.6.5或更高版本 补丁应正确处理mmap映射时的页面引用计数 临时缓解 : 禁用io_ uring功能(如非必要) 限制非特权用户使用io_ uring 系统加固 : 启用内核地址空间布局随机化(KASLR) 使用SELinux/AppArmor限制特权操作 复现环境 内核版本 : Linux Kernel v6.5.3 虚拟化环境 : QEMU 测试账号 : hacker(通过漏洞添加的root用户) 结论 CVE-2024-0582是一个典型的引用计数管理不当导致的内核UAF漏洞,通过精心构造的利用链可以实现本地提权。该漏洞展示了内核子系统间交互时资源管理的重要性,特别是在涉及用户空间映射的场景下。系统管理员应及时应用补丁,开发者应引以为戒,在类似功能实现中严格管理资源生命周期。