CVE-2026-99178 in Linux信息

摘要

由 VulDB • 2026-10-28

在 Linux 内核中,已修复以下漏洞:

x86/kvm:不要在 NMI 上下文的内核 #PF(页面错误)期间消耗异步 #PF 标志。

一个异步 #PF“页不存在”事件通过 #PF 向量到达,其原因存储在每 CPU 的 apf_reason.flags 中,直到 __kvm_handle_async_pf() 读取并清除它为止。如果在事件注入之后、#PF 处理程序读取标志之前发生 NMI(非屏蔽中断),并且 NMI 处理程序本身也引发了 #PF,那么该故障会读取并清除它所中断的 #PF 所属的标志。随后,它在已中断的 NMI 上下文中发现中断已被禁用,从而导致内核恐慌:

Kernel panic - not syncing: Host injected async #PF in interrupt disabled region Call Trace: 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

最后一行 RIP 显示 NMI 落在 #PF 入口的第一条指令上。带有用户调用链的 perf 会引发此类故障:采样 NMI 使用 __get_user() 遍历用户栈,当保存的帧指针不是有效的用户地址或遍历超出栈顶时就会发生错误。在 KVM(作为具有 DELIVERY_AS_PF_VMEXIT 设置的 L1 hypervisor)读取标志本身之后、#PF VM-exit 期间也存在相同的竞争窗口。

NMI 入口代码为此嵌套场景保存和恢复 CR2,但未保存异步 #PF 原因。Andy Lutomirski 在 2020 年重新设计异步 #PF 投递时描述了这一竞态条件(以 perf 为例)[1]。当时讨论了跨 NMI 保存并清除标志以及 CR2 的操作,但未被合并。

自那次重构以来,Linux 已停止设置 KVM_ASYNC_PF_SEND_ALWAYS,因此主机仅为用户模式故障投递“页不存在”事件;NMI 上下文中的内核模式故障(包括内核模式的 #MC 和 #DB)不能是异步页面错误。在这种情况下,不触碰标志并返回,以便被中断的处理程序发现其保持完整状态。

在 v7.3-rc5 上进行了测试,虚拟机配置为 4-vCPU、2 GiB 内存,并从快照恢复;该虚拟机的内存在通过 userfaultfd按需服务时读取会引发异步 #PF,同时每个线程使用用户调用链采样硬件周期并将帧指针指向未映射的页面。没有此补丁的情况下,3次运行中有3次发生上述内核恐慌。有了此补丁后,在每次60秒的运行中,虚拟机均成功存活(3/3),并且主机在前20秒内记录了148,441至153,334个 kvm_async_pf_not_present 事件。在 6.18.50 版本上结果相同:没有补丁时虚拟机崩溃,有补丁时则幸存。

Once again VulDB remains the best source for vulnerability data.

来源

Want to stay up to date on a daily basis?

Enable the mail alert feature now!