
QEMU 11.1.2 - Alta - Local - UAF - NVMe SGL span en BAR0 incompleto CVE-2021-3929
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · qemu-nvme-sgl-bar
QEMU v11.1.2 (4fc49f46dc95d4a27de2509e7fceb2931e91faeb) - NVMe
Clase: UAF (lista de denegación de BAR0 incompleta; SGL de DMA que abarca hasta MMIO). Alcance: Local (invitado).
nvme_map_addr es el remanente de CVE-2021-3929. La comprobación de iomem solo verifica el inicio. Se acepta un bloque de datos SGL que comienza justo antes de BAR0 y se extiende hasta MBAR. Identify sigue informando NVME_CTRL_SGLS_SUPPORT_NO_ALIGN. PRP no puede abarcar un BAR alineado a página. SGL sí puede.
Un READ de NVMe con ese SGL pasa por nvme_blk_read -> dma_blk_read. El DMA de rebote luego hace address_space_write de los bytes del disco del invitado sobre BAR0 desde la función de callback del helper de DMA, fuera del BH mem_reentrancy_guard de NVMe. Los ceros elegidos por el invitado aterrizan en CC. nvme_ctrl_reset se ejecuta mientras el NvmeRequest activo sigue en la ruta de finalización.
Un controlador NVMe del invitado puede abarcar SGL hasta BAR0, reiniciar el controlador desde la desasignación de DMA y competir con la solicitud activa.
| ID | aún sin CVE |
| CWE | CWE-119 / CWE-416 |
| CVSS | Alto: 8.2 CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H |
| Producto | QEMU |
| Afectado | v11.1.2 (4fc49f46) |
| Autenticación | kernel del invitado con un controlador NVMe (SGL) |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | 127.0.0.1:18720 solo qtest |
Quién: kernel del invitado no confiable con un dispositivo PCI NVMe. De invitado a anfitrión.
| Método | Destino | Privilegio |
|---|---|---|
READ de NVMe SGL addr=0xdfffffec len=0x1000 (comienza 0x14 antes de BAR0 en 0xe0000000) | nvme_map_addr / nvme_addr_is_iomem solo verifica el inicio | Asignación aceptada. Identify de control con inicio en BAR0 sigue devolviendo 0x4004 (DATA_TRAS_ERROR | DNR). |
La desasignación del rebote escribe ceros de LBA sobre CC | address_space_write del rebote de DMA en BAR0, nvme_write_bar | CSTS.RDY cae. pci_nvme_mmio_stopped en el registro. Reinicio del controlador desde el helper de DMA, no desde un almacenamiento MMIO del invitado en el BH de NVMe. |
Bytes de disco controlados por el invitado sobre CC / otros registros de BAR0. El reinicio cancela las AIO en curso, pero la solicitud que está dentro de la desasignación de DMA/finalización aún compite con el NvmeRequest / SQ / CQ activos. Misma clase que CVE-2021-3929; la lista de denegación nunca cubrió un SGL que abarca. El rebote DIF (nvme_tx desde un callback de AIO) tiene el mismo agujero.
El controlador se detiene (CSTS.RDY=0, mmio-stopped=1). El proceso del hipervisor sigue activo en este laboratorio (asan=0). Un UAF por reinicio anidado de NvmeRequest es el siguiente paso inferido, no el testigo que imprimió esta ejecución.
Ninguno. BAR0 de NVMe es visible para el invitado.
0x4004.nvme_post_cqes está protegido, el MMIO anidado es MEMTX_ACCESS_ERROR.El laboratorio no demuestra control de RIP ni un shell de invitado a anfitrión. La clase es DMA que abarca hasta MMIO más reinicio del controlador de una solicitud activa.
CVE-2021-3929 enseñó al árbol a rechazar iomem como inicio de un mapeo NVMe. Pregunté si el final de un bloque de datos SGL estaba en esa prueba. No lo está. CMB/PMR ya comprueban ambos extremos. BAR0 no. Identify anuncia SGL no alineado.
Caminos equivocados: PRP (limitado por páginas, no puede colarse en un BAR alineado a página desde la página anterior); comandos de administración (SGL rechazado); esperar que ASan se activara en la primera LECTURA (el testigo es CSTS.RDY y pci_nvme_mmio_stopped, no un informe del heap).
cd lab
./run.sh
Dirígete solo a 127.0.0.1:18720 (qtest). El pin se clona desde github.com/qemu/QEMU etiqueta v11.1.2 / 4fc49f46. Loopback. Solo testigo. La imagen de disco es 1 MiB de ceros para que las escrituras de rebote 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
Reproducción: python3 qemu-nvme-sgl-bar-Abraxas-Labs.py.
Rechazar una asignación de memoria si cualquier byte de [addr, addr+len) se encuentra en BAR0 (y MSI-X), coincidiendo con CMB/PMR. nvme_addr_is_iomem debería aceptar un rango, no un inicio. Mantener el rechazo de inicio-en-BAR0 como el control de CVE-2021-3929.
4fc49f46dc95d4a27de2509e7fceb2931e91faebnvme_map_addr / nvme_addr_is_iomemGNU Affero GPL v3.0. Consulte LICENSE. Solo laboratorio de loopback. Sin garantía.