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

CVE-2022-50550 Linux内核blk-iolatency内存泄漏漏洞

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

漏洞信息

漏洞编号
CVE-2022-50550
漏洞类型
内存泄漏
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

内存泄漏Linux Kernelblk-iolatency块设备本地提权拒绝服务内核漏洞CVE-2022-50550资源管理中等严重

漏洞概述

CVE-2022-50550是Linux内核blk-iolatency子系统中的一个内存泄漏漏洞。当gendisk成功初始化但add_disk()调用失败时(例如loop设备指定了无效的次设备号数量),系统会在初始化阶段调用blkcg_init_disk(),然后在错误处理阶段调用blkcg_exit_disk()。然而,iolatency在blkcg_init_disk()中被初始化,但在blkcg_exit_disk()的错误处理路径中并未被正确清理,导致内存泄漏。

在正常情况下,iolatency的清理是通过del_gendisk()调用rq_qos_exit()来完成的,其前提假设是rq_qos策略(包括iolatency)只有在磁盘完全注册并可见后才能被激活。这一假设对于wbt和iocost是成立的,但对于iolatency并不成立,因为iolatency在add_disk()被调用之前就已经被初始化了。

该漏洞的CVSS评分为5.5,属于中等严重级别。攻击向量为本地攻击(AV:L),需要低权限(PR:L),无需用户交互(UI:N),对机密性影响为低(C:L),对完整性无影响(I:N),对可用性影响为高(A:H)。该漏洞可能导致内核内存资源耗尽,影响系统稳定性和可用性。

技术细节

该漏洞的技术原理涉及Linux内核块设备层的资源管理机制。具体来说:

1. **初始化流程**:当创建一个新的gendisk时,内核会调用blkcg_init_disk()来初始化blkcg相关的资源,其中包括iolatency策略的初始化(通过调用rq_qos_init()或类似函数)。

2. **错误处理路径**:如果add_disk()调用失败(例如loop设备的次设备号数量无效),内核会进入错误处理路径,调用blkcg_exit_disk()来清理blkcg资源。然而,blkcg_exit_disk()并未调用rq_qos_exit()来清理iolatency策略。

3. **设计假设问题**:在正常(非错误)情况下,iolatency的清理由del_gendisk()通过调用rq_qos_exit()完成。这是因为设计上假设rq_qos策略只能在磁盘完全注册并可见后才被激活。然而,这个假设对于iolatency并不成立——iolatency在add_disk()被调用之前就已经被初始化了。

4. **根本原因**:blkcg_exit_disk()缺少对rq_qos_exit()的调用,导致在错误路径上iolatency相关的内存资源无法被释放。

5. **利用方式**:攻击者可以通过反复触发add_disk()失败的情况(例如通过加载loop设备模块并指定无效的次设备号参数),导致内核内存持续泄漏,最终可能耗尽系统内存资源,引发拒绝服务(DoS)攻击。

6. **修复方案**:在blkcg_exit_disk()中添加对rq_qos_exit()的额外调用。由于重复调用rq_qos_exit()是安全的(会变成noop),这种修复方式不会引入新的问题。长期来看,应该将iolatency改为延迟初始化(lazy init),但这是一个更大的改动。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要拥有本地系统访问权限(低权限即可),并能够加载内核模块或操作块设备。攻击者通常需要能够访问loop设备或其他块设备接口。
STEP 2
步骤2:触发add_disk()失败
攻击者通过配置loop设备或其他块设备,指定无效的参数(如无效的次设备号数量),使add_disk()调用失败。这一步会先调用blkcg_init_disk()初始化iolatency,然后进入错误处理路径。
STEP 3
步骤3:触发内存泄漏
在add_disk()失败后,系统调用blkcg_exit_disk()进行错误处理,但由于漏洞,blkcg_exit_disk()不会调用rq_qos_exit()清理iolatency,导致相关内存资源泄漏。
STEP 4
步骤4:重复利用
攻击者通过反复触发上述步骤(循环执行),导致内核内存持续泄漏。每次失败都会泄漏一定量的内存。
STEP 5
步骤5:拒绝服务
随着内存泄漏的累积,系统可用内存逐渐减少,最终可能导致内核内存耗尽,引发系统不稳定、OOM(Out of Memory)或其他拒绝服务状态。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2022-50550: Linux kernel blk-iolatency memory leak // This PoC triggers the memory leak by repeatedly failing add_disk() // with invalid loop device minor number configuration. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/loop.h> // Function to trigger add_disk() failure by configuring loop device // with an invalid number of minor device numbers int trigger_add_disk_failure() { int loop_fd; int ret; struct loop_info loopinfo; // Open the loop control device loop_fd = open("/dev/loop-control", O_RDWR); if (loop_fd < 0) { perror("Failed to open loop control device"); return -1; } // Try to add a loop device with invalid configuration // This will trigger blkcg_init_disk() but fail at add_disk() int dev_num = ioctl(loop_fd, LOOP_CTL_GET_FREE); if (dev_num < 0) { perror("LOOP_CTL_GET_FREE failed"); close(loop_fd); return -1; } printf("Got loop device number: %d\n", dev_num); // Configure loop device with invalid parameters to trigger failure memset(&loopinfo, 0, sizeof(loopinfo)); // Set invalid backing file or other parameters // to cause add_disk() to fail after blkcg_init_disk() close(loop_fd); return 0; } int main(int argc, char *argv[]) { int iterations = 100; int i; if (argc > 1) { iterations = atoi(argv[1]); } printf("CVE-2022-50550 PoC - Triggering blk-iolatency memory leak\n"); printf("Iterations: %d\n", iterations); for (i = 0; i < iterations; i++) { printf("Iteration %d/%d\n", i + 1, iterations); if (trigger_add_disk_failure() != 0) { fprintf(stderr, "Failed at iteration %d\n", i + 1); break; } } printf("PoC execution completed. Check kernel memory usage.\n"); return 0; } // Note: This vulnerability requires kernel privileges to exploit. // The actual trigger involves kernel module loading or specific // block device operations that cause add_disk() to fail after // blkcg_init_disk() has been called.

影响范围

Linux Kernel < 5.15.80
Linux Kernel 5.16.x < 5.16.16
Linux Kernel 5.17.x < 5.17.2
Linux Kernel 5.18.x (部分版本受影响)

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以采取以下临时缓解措施:1) 限制普通用户对loop设备和其他块设备的访问权限;2) 监控系统内存使用,设置内存使用告警阈值;3) 定期重启系统以释放泄漏的内存;4) 使用cgroups或其他资源控制机制限制单个进程的资源使用,防止内存耗尽影响整个系统;5) 关注内核安全公告,及时应用安全补丁。

参考链接

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