
QEMU 11.1.2 — высокий уровень — локальная — UAF — NVMe SGL span в BAR0 неполный CVE-2021-3929
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · qemu-nvme-sgl-bar
QEMU v11.1.2 (4fc49f46dc95d4a27de2509e7fceb2931e91faeb) - NVMe
Класс: UAF (неполный deny-list BAR0; SGL DMA с выходом за границы в MMIO). Доступ: локальный (гость).
nvme_map_addr — это остаток от CVE-2021-3929. Проверка iomem выполняется только для начального адреса. Блок данных SGL, который начинается чуть раньше BAR0 и заходит в MBAR, принимается. Identify по-прежнему сообщает NVME_CTRL_SGLS_SUPPORT_NO_ALIGN. PRP не может пересекать выровненный по странице BAR. SGL может.
NVMe READ с таким SGL проходит через nvme_blk_read -> dma_blk_read. Bounce DMA затем выполняет address_space_write байтов гостевого диска в BAR0 из callback-функции DMA-хелпера, вне BH mem_reentrancy_guard NVMe. Выбранные гостем нули попадают в 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 |
Кто: недоверенное гостевое ядро с PCI-устройством NVMe. От гостя к хосту.
| Метод | Точка сброса | Привилегия |
|---|---|---|
NVMe READ SGL addr=0xdfffffec len=0x1000 (начинается за 0x14 до BAR0 по адресу 0xe0000000) | nvme_map_addr / nvme_addr_is_iomem только для начального адреса | Отображение принято. Control Identify с началом в BAR0 по-прежнему возвращает 0x4004 (DATA_TRAS_ERROR | DNR). |
Bounce unmap записывает нули LBA в CC | address_space_write DMA bounce в BAR0, nvme_write_bar | CSTS.RDY сбрасывается. В журнале pci_nvme_mmio_stopped. Сброс контроллера из DMA-хелпера, а не из гостевой записи MMIO в BH NVMe. |
Управляемые гостем байты диска в CC / других регистрах BAR0. Сброс отменяет inflight AIO, но запрос, который находится внутри DMA unmap/завершения, всё ещё участвует в гонке с живым NvmeRequest / SQ / CQ. Тот же класс, что и CVE-2021-3929; deny-list никогда не покрывал SGL с выходом за границы. Bounce DIF (nvme_tx из callback-функции AIO) имеет ту же дыру.
Контроллер останавливается (CSTS.RDY=0, mmio-stopped=1). Процесс гипервизора в этой лаборатории остаётся запущенным (asan=0). Вложенный UAF NvmeRequest при сбросе — предполагаемый следующий шаг, а не свидетельство, которое вывел этот запуск.
Нет. BAR0 NVMe виден гостю.
0x4004.nvme_post_cqes защищён, вложенный MMIO даёт MEMTX_ACCESS_ERROR.Лаборатория не демонстрирует контроль RIP или оболочку от гостя к хосту. Класс — это 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. Loopback. Только свидетель. Образ диска — 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. Только для локальной лаборатории. Без гарантий.