{"schema":"threatline.record/2","record":{"id":"CVE-2026-99178","aliases":[],"summary":"x86/kvm: Don't consume async #PF flags on a kernel #PF in NMI context","details":"In the Linux kernel, the following vulnerability has been resolved:\n\nx86/kvm: Don't consume async #PF flags on a kernel #PF in NMI context\n\nAn async #PF \"page not present\" event arrives through the #PF vector,\nand its reason sits in the per-CPU apf_reason.flags until\n__kvm_handle_async_pf() reads and clears it. If an NMI arrives after\nthe event is injected and before the #PF handler reads the flags, and\nthe NMI handler itself takes a #PF, that fault reads and clears the\nflags belonging to the #PF it interrupted. It then finds interrupts\ndisabled in the NMI context it interrupted, and panics:\n\n  Kernel panic - not syncing: Host injected async #PF in interrupt\ndisabled region\n  Call Trace:\n   <NMI>\n   panic+0x52/0x60\n   __kvm_handle_async_pf+0xb0/0xb0\n   exc_page_fault+0x71/0xb0\n   asm_exc_page_fault+0x27/0x30\n  RIP: 0010:__get_user_nocheck_8+0x6/0x20\n   perf_callchain_user+0x147/0x1a0\n   get_perf_callchain+0x12d/0x1c0\n   ...\n   perf_event_nmi_handler+0x26/0x50\n   exc_nmi+0xe8/0x110\n  RIP: 0010:asm_exc_page_fault+0x0/0x30\n   </NMI>\n\nThe last RIP line shows the NMI landing on the first instruction of\nthe #PF entry. perf with user call chains takes such a fault: the\nsampling NMI walks the user stack with __get_user(), which faults when\na saved frame pointer is not a valid user address or the walk runs off\nthe top of the stack. The same window exists when KVM, running as an\nL1 hypervisor with DELIVERY_AS_PF_VMEXIT, reads the flags itself after\na #PF VM-exit.\n\nThe NMI entry code saves and restores CR2 for this nesting, but not the\nasync #PF reason. Andy Lutomirski described the race, with perf as the\nexample, when async #PF delivery was reworked in 2020 [1]. Saving and\nclearing the flags across the NMI, next to CR2, was discussed there but\nnot merged.\n\nSince that rework, Linux has stopped setting KVM_ASYNC_PF_SEND_ALWAYS,\nso the host delivers \"page not present\" only for user mode faults and\na kernel-mode fault in NMI context (including kernel-mode #MC and #DB)\ncannot be an async page fault.  In that case, return without touching\nthe flags so that the interrupted handler finds them intact.\n\nTested on v7.3-rc5 in a 4-vCPU, 2 GiB guest restored from a snapshot\nwhose memory is served on demand through userfaultfd, so that reading\nit back takes async #PFs, while every thread samples hardware cycles\nwith user call chains and points its frame pointer at an unmapped page.\nWithout this patch the guest panicked as above in 3 of 3 runs. With it,\nthe guest survived 3 of 3 runs of 60 seconds, and the host counted\n148,441 to 153,334 kvm_async_pf_not_present events in the first 20\nseconds of each. On 6.18.50 the results were the same: the guest\npanicked without the patch and survived with it.","categories":["Operating systems"],"product":"Linux","vendor":"Linux","ecosystem":null,"affected_ranges":[{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","source_modified_at":"2026-10-28T10:35:31.961Z","fetched_at":"2026-10-28T15:55:58.673066Z","product":"Linux","vendor":"Linux","versions":[{"version":"1da177e4c3f41524e886b7f1b8a0c1fc7321cac2","lessThan":"b77e9622bbade9812e2090c66d25c372f515e921","status":"affected","versionType":"git"},{"version":"1da177e4c3f41524e886b7f1b8a0c1fc7321cac2","lessThan":"f45ee1ff6358a22d7e22a4c53cb3148ea97b10d9","status":"affected","versionType":"git"},{"version":"1da177e4c3f41524e886b7f1b8a0c1fc7321cac2","lessThan":"81d99abe2bd81379abfb595e403bbbee6fbfc624","status":"affected","versionType":"git"},{"version":"0","lessThan":"6.18.59","status":"affected","versionType":"semver"},{"version":"0","lessThan":"7.2.13","status":"affected","versionType":"semver"}],"defaultStatus":"unaffected"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","source_modified_at":"2026-10-28T10:35:31.961Z","fetched_at":"2026-10-28T15:55:58.673066Z","product":"Linux","vendor":"Linux","versions":[{"version":"6.18.59","lessThanOrEqual":"6.18.*","status":"unaffected","versionType":"semver"},{"version":"7.2.13","lessThanOrEqual":"7.2.*","status":"unaffected","versionType":"semver"},{"version":"7.3","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}],"defaultStatus":"affected"}],"fixed_versions":[{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","source_modified_at":"2026-10-28T10:35:31.961Z","fetched_at":"2026-10-28T15:55:58.673066Z","package":{"name":"Linux","ecosystem":null},"version":"81d99abe2bd81379abfb595e403bbbee6fbfc624","basis":"first unaffected version stated in the CVE record"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","source_modified_at":"2026-10-28T10:35:31.961Z","fetched_at":"2026-10-28T15:55:58.673066Z","package":{"name":"Linux","ecosystem":null},"version":"6.18.59","basis":"first unaffected version stated in the CVE record"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","source_modified_at":"2026-10-28T10:35:31.961Z","fetched_at":"2026-10-28T15:55:58.673066Z","package":{"name":"Linux","ecosystem":null},"version":"7.2.13","basis":"first unaffected version stated in the CVE record"}],"cvss":null,"severity":null,"kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-28T10:35:31.961Z","modified_at":"2026-10-28T10:35:31.961Z","provenance":[{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-99178","fetched_at":"2026-10-28T15:55:58.673066Z","source_modified_at":"2026-10-28T10:35:31.961Z"}],"sources":["CVE List"],"references":[{"source":"CVE List","url":"https://git.kernel.org/stable/c/b77e9622bbade9812e2090c66d25c372f515e921"},{"source":"CVE List","url":"https://git.kernel.org/stable/c/f45ee1ff6358a22d7e22a4c53cb3148ea97b10d9"},{"source":"CVE List","url":"https://git.kernel.org/stable/c/81d99abe2bd81379abfb595e403bbbee6fbfc624"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"product","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-28T10:35:31.961Z","content_hash":"cda0d3c8e5c055c0242783a92c1e0800c9f05df4c68331a3a63390ea72b30ba3"}}
