CVE-2023-53656CVE-2023-53656是Linux内核中hisi PCIe PMU(Performance Monitoring Unit)驱动的一个高可用性影响漏洞。该漏洞位于Linux内核的drivers/perf子系统中的hisi PCIe PMU驱动模块中。
在CPU热插拔(hotplug)过程中,当某个CPU即将下线(teardown)时,驱动需要将当前绑定在该CPU上的perf监控上下文(perf context)迁移到其他仍然在线的CPU上。然而,由于在调用cpuhp::teardown()回调时,cpu_online_mask()尚未更新,仍然包含了即将下线的CPU。这导致驱动在选择目标CPU时,可能错误地将perf上下文迁移到了正在执行teardown操作的CPU自身,从而引发死锁。
具体表现为:在CPU下线过程中,hisi_pcie_pmu_offline_cpu回调尝试获取一个互斥锁(mutex),但由于上下文被迁移到了同一个正在执行teardown的CPU上,导致该CPU在等待自己释放锁,形成自死锁(self-deadlock),系统出现不可恢复的挂起状态。
该漏洞的CVSS评分为5.5,属于中危级别。虽然攻击需要本地低权限访问且无需用户交互,但其对系统可用性的影响为高,可能导致系统完全挂起,需要硬重启才能恢复。该漏洞影响使用华为海思(HiSilicon)硬件平台并启用了hisi PCIe PMU驱动的Linux系统。
该漏洞的技术根源在于CPU热插拔过程中CPU在线掩码(cpu_online_mask)的更新时机与驱动迁移逻辑之间的竞态条件。
在Linux内核的CPU热插拔框架中,当一个CPU即将下线时,系统会按顺序调用CPUHP_TEARDOWN_CPU回调链上的各个回调函数。对于hisi PCIe PMU驱动,其hisi_pcie_pmu_offline_cpu()回调负责将绑定在该CPU上的perf事件上下文迁移到其他在线CPU。
关键问题在于:在调用cpuhp::teardown()回调时,cpu_online_mask()尚未更新,它仍然包含了正在执行teardown的CPU。这意味着当驱动使用cpumask_any_but()或类似的API来选择目标迁移CPU时,可能会选择到正在teardown的CPU本身。
当perf上下文被迁移到正在teardown的CPU时,会调用perf_pmu_migrate_context()函数,该函数需要获取pmu->ctx_mutex锁。然而,由于该CPU上的cpuhp线程本身也在等待获取同一个锁(在hisi_pcie_pmu_offline_cpu中调用mutex_lock),导致经典的ABBA死锁:
- CPU线程持有ctx_mutex,等待完成teardown
- cpuhp线程等待ctx_mutex以完成迁移
修复方案是使用cpumask_any_but()函数明确排除正在teardown的CPU,确保迁移目标CPU是真正活跃的CPU,从而避免自死锁问题。
利用方式:该漏洞为本地触发,攻击者无需特殊权限即可触发CPU下线操作(例如通过/sys/devices/system/cpu/cpuX/offline),在特定时序条件下触发死锁,导致系统不可用。