中危 bpf:修复 ringbuf 中的溢出预留(CVE-2024-41009)

CVE编号

CVE-2024-41009

利用情况

暂无

补丁情况

官方补丁

披露时间

2024-07-17
漏洞描述
在Linux内核中,已经修复了以下漏洞:bpf:修复ringbuf上的预留溢出问题BPF环形缓冲区内部实现为一个以2的幂为大小的循环缓冲区,有两个不断增长的逻辑计数器:consumer_pos表示消费者已经消费数据的逻辑位置,producer_pos表示所有生产者已预留的数据量。每次记录被预留时,拥有该记录的制作者会成功推进制作者计数器。在用户空间,每次读取一条记录时,消费者会在完成处理数据后推进消费者计数器。这两个计数器存储在单独的页面中,因此在用户空间中,制作者计数器是只读的,消费者计数器是可读写的。一个简化并因此加快生产者和消费者实现的方面是如何在虚拟内存中连续映射数据区域两次。这允许我们无需对在环形缓冲区数据区域末尾需要环绕的样本采取任何特殊措施,因为最后一页数据之后的下一页将再次成为第一页数据,从而在虚拟内存中仍然完全连续。每条记录都有一个bpf_ringbuf_hdr { u32 len; u32 pg_off; }结构来保持长度和偏移量,并且对于BPF程序是不可访问的。像bpf_ringbuf_reserve()这样的助手函数会返回(void *)hdr + BPF_RINGBUF_HDR_SZ供BPF程序使用。然而,Bing-Jhong和Muhammad报告说,有可能使第二个分配的内存块与第一个块重叠,结果导致BPF程序能够编辑第一个块的头部。例如,假设创建一个类型为BPF_MAP_TYPE_RINGBUF的映射,其大小为0x4000。接下来,在调用bpf_ringbuf_reserve()之前修改consumer_pos为0x3000。这将分配一个块A,位于[0x0,0x3008],并且BPF程序能够编辑[0x8,0x3008]。现在,让我们分配一个大小为0x3000的块B。由于提前修改了consumer_pos以通过`new_prod_pos - cons_pos > rb->mask`检查,因此这将成功。块B将在范围[0x3008,0x6010],并且BPF程序能够编辑[0x3010,0x6010]。由于前面提到的环形缓冲区内存布局,范围[0x0,0x4000]和[0x4000,0x8000]指向相同的数据页面。这意味着块B在[0x4000, 0x4008]是块A的头部。bpf_ringbuf_submit() / bpf_ringbuf_discard()使用头部的pg_off通过bpf_ringbuf_restore_from_rec()找到bpf_ringbuf。一旦块B修改了块A的头部,那么bpf_ringbuf_commit()就会引用错误的页面并可能导致崩溃。通过计算最旧的pending_pos并检查从最旧的未决记录到最新的记录的范围是否会超出环形缓冲区大小来解决这个问题。如果是这种情况,则拒绝请求。我们在BPF自测试中的环形缓冲区基准测试(./benchs/run_bench_ringbufs.sh)之前和之后进行了测试,虽然在一些基准测试中看起来慢了一些,但影响并不显著。
解决建议
建议您更新当前系统或软件至最新版,完成漏洞的修复。
受影响软件情况
# 类型 厂商 产品 版本 影响面
1
运行在以下环境
系统 debian_12 linux * Up to
(excluding)
6.1.98-1
运行在以下环境
系统 linux linux_kernel * From
(including)
5.8
Up to
(excluding)
6.1.97
运行在以下环境
系统 linux linux_kernel * From
(including)
6.2
Up to
(excluding)
6.6.37
运行在以下环境
系统 linux linux_kernel * From
(including)
6.7
Up to
(excluding)
6.9.8
阿里云评分
5.0
  • 攻击路径
    本地
  • 攻击复杂度
    困难
  • 权限要求
    管控权限
  • 影响范围
    有限影响
  • EXP成熟度
    未验证
  • 补丁情况
    官方补丁
  • 数据保密性
    无影响
  • 数据完整性
    无影响
  • 服务器危害
    无影响
  • 全网数量
    N/A
CWE-ID 漏洞类型
CWE-770 不加限制或调节的资源分配
阿里云安全产品覆盖情况