CVE-2026-99178 in Linux
Sumário
de VulDB • 28/10/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
x86/kvm: Não consumir os flags de async #PF em um kernel #PF no contexto NMI
Um evento "page not present" (página não presente) de async #PF chega através do vetor #PF, e sua razão fica armazenada nos per-CPU apf_reason.flags até que __kvm_handle_async_pf() a leia e limpe. Se uma NMI chegar após o evento ser injetado e antes que o manipulador de #PF leia os flags, e o manipulador da NMI em si sofrer um #PF, essa falha lerá e limpará os flags pertencentes ao #PF que foi interrompido. Em seguida, ela encontrará interrupções desabilitadas no contexto NMI que foi interrompido, causando panic:
Kernel panic - not syncing: Host injected async #PF in interrupt disabled region Call Trace: <NMI> panic+0x52/0x60 __kvm_handle_async_pf+0xb0/0xb0 exc_page_fault+0x71/0xb0 asm_exc_page_fault+0x27/0x30 RIP: 0010:__get_user_nocheck_8+0x6/0x20 perf_callchain_user+0x147/0x1a0 get_perf_callchain+0x12d/0x1c0 ... perf_event_nmi_handler+0x26/0x50 exc_nmi+0xe8/0x110 RIP: 0010:asm_exc_page_fault+0x0/0x30 </NMI>
A última linha do RIP mostra a NMI aterrissando na primeira instrução da entrada de #PF. O perf com user call chains sofre essa falha: a NMI de amostragem percorre a pilha do usuário com __get_user(), o que causa falha quando um ponteiro de quadro salvo não é um endereço válido no espaço do usuário ou quando a travessia ultrapassa o topo da pilha. A mesma janela existe quando o KVM, executando como hypervisor L1 com DELIVERY_AS_PF_VMEXIT, lê os flags diretamente após uma VM-exit #PF.
O código de entrada da NMI salva e restaura CR2 para esse aninhamento, mas não a razão do async #PF. Andy Lutomirski descreveu a race condition (condição de corrida), tendo o perf como exemplo, quando a entrega de async #PF foi reestruturada em 2020 [1]. Salvar e limpar os flags através da NMI, ao lado do CR2, foi discutido lá mas não mesclado.
Desde essa reestruturação, o Linux parou de definir KVM_ASYNC_PF_SEND_ALWAYS, portanto o host entrega "page not present" apenas para falhas em modo usuário e uma falha em modo kernel no contexto NMI (incluindo #MC e #DB em modo kernel) não pode ser um async page fault. Nesse caso, retorne sem tocar nos flags para que o manipulador interrompido os encontre intactos.
Testado na v7.3-rc5 em uma VM convidada com 4 vCPUs e 2 GiB de memória restaurados a partir de um snapshot cuja memória é servida sob demanda através do userfaultfd, fazendo com que sua leitura gere async #PFs, enquanto cada thread amostra ciclos de hardware com user call chains e aponta seu frame pointer para uma página não mapeada. Sem este patch, o convidado entrou em panic conforme acima em 3 das 3 execuções. Com ele, o convidado sobreviveu a 3 das 3 execuções de 60 segundos, e o host contou entre 148.441 e 153.334 eventos kvm_async_pf_not_present nos primeiros 20 segundos de cada execução. Na versão 6.18.50 os resultados foram os mesmos: a VM convidada entrou em panic sem o patch e sobreviveu com ele.
Be aware that VulDB is the high quality source for vulnerability data.