abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · qemu-nvme-sgl-bar
QEMU v11.1.2 (4fc49f46dc95d4a27de2509e7fceb2931e91faeb) - NVMe
类别: UAF(BAR0 拒绝列表不完整;跨界的 SGL DMA 进入 MMIO)。可达性: 本地(客户机)。
nvme_map_addr 是 CVE-2021-3929 的遗留问题。iomem 检查只检查起始地址。一个起始于 BAR0 之前、延伸进 MBAR 的 SGL 数据块会被接受。Identify 仍然报告 NVME_CTRL_SGLS_SUPPORT_NO_ALIGN。PRP 无法跨越页对齐的 BAR。SGL 可以。
使用该 SGL 的 NVMe READ 会经过 nvme_blk_read -> dma_blk_read。随后 bounce DMA 在 DMA 辅助回调中通过 address_space_write 将客户机磁盘字节写入 BAR0,且位于 NVMe mem_reentrancy_guard BH 之外。客户机选择的零值落在 CC 上。nvme_ctrl_reset 在活跃的 NvmeRequest 仍处于完成路径时运行。
客户机 NVMe 驱动可以将 SGL 跨界到 BAR0,从 DMA unmap 中重置控制器,并与活跃请求竞争。
| ID | 暂无 CVE |
| CWE | CWE-119 / CWE-416 |
| CVSS | 高危:8.2 CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H |
| 产品 | QEMU |
| 受影响版本 | v11.1.2 (4fc49f46) |
| 认证 | 带有 NVMe 控制器(SGL)的客户机内核 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 127.0.0.1:18720 仅 qtest |
谁:拥有 NVMe PCI 设备的不可信客户机内核。客户机到宿主机。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
NVMe READ SGL addr=0xdfffffec len=0x1000(起始于 BAR0 之前 0x14,BAR0 位于 0xe0000000) | nvme_map_addr / nvme_addr_is_iomem 仅检查起始地址 | 映射被接受。起始地址在 BAR0 内的 Control Identify 仍返回 0x4004(DATA_TRAS_ERROR | DNR)。 |
Bounce unmap 将 LBA 零值写入 CC | DMA bounce 的 address_space_write 写入 BAR0,nvme_write_bar | CSTS.RDY 下降。 日志中出现 pci_nvme_mmio_stopped。控制器重置来自 DMA 辅助函数,而非 NVMe BH 中的客户机 MMIO 存储。 |
客户机控制的磁盘字节落在 CC / 其他 BAR0 寄存器上。重置会取消进行中的 AIO,但处于 DMA unmap/完成过程中的请求仍会与活跃的 NvmeRequest / SQ / CQ 竞争。与 CVE-2021-3929 同类;拒绝列表从未覆盖跨界的 SGL。DIF bounce(来自 AIO 回调的 nvme_tx)存在同样的漏洞。
控制器停止(CSTS.RDY=0,mmio-stopped=1)。在此实验环境中,虚拟机监控程序进程保持运行(asan=0)。NvmeRequest 的嵌套重置 UAF 是推断的下一步,而非本次运行打印出的见证。
无。NVMe BAR0 对客户机可见。
0x4004。nvme_post_cqes BH 受保护,嵌套 MMIO 为 MEMTX_ACCESS_ERROR。该实验未演示 RIP 控制或客户机到宿主机的 shell。该类别是跨界 DMA 进入 MMIO 加上对活跃请求的控制器重置。
CVE-2021-3929 让代码树学会拒绝将 iomem 作为 NVMe 映射的起始地址。我询问过 SGL 数据块的结束地址是否在该测试中。答案是否定的。CMB/PMR 已经检查了两端。BAR0 没有。Identify 会通告未对齐的 SGL。
错误方向:PRP(受页边界限制,无法从上一页潜入页对齐的 BAR);管理命令(SGL 被拒绝);指望 ASan 在第一次 READ 时触发(见证者是 CSTS.RDY 和 pci_nvme_mmio_stopped,而不是堆报告)。
cd lab
./run.sh
仅针对 127.0.0.1:18720(qtest)。Pin 克隆自 github.com/qemu/QEMU 标签 v11.1.2 / 4fc49f46。回环。仅见证。磁盘镜像为 1 MiB 的零,因此 bounce 写入 CC.EN=0。
SUCCESS qemu-nvme-sgl-bar control-sc=0x4004 span-addr=0xdfffffec span-end=0xe0000fec csts-rdy-before=1 csts-rdy-after=0 mmio-stopped=1 asan=0 QEMU-NVME-SGL-BAR-WITNESS
复现:python3 qemu-nvme-sgl-bar-Abraxas-Labs.py。
如果 [addr, addr+len) 中的任何一个字节落在 BAR0(以及 MSI-X)内,就拒绝该映射,与 CMB/PMR 的处理保持一致。nvme_addr_is_iomem 应当接收一个范围,而不是一个起始地址。保留“起始地址位于 BAR0 内即拒绝”这一逻辑,作为 CVE-2021-3929 的防护措施。
4fc49f46dc95d4a27de2509e7fceb2931e91faebnvme_map_addr / nvme_addr_is_iomemGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境使用。不提供任何担保。