In the Linux kernel, the following vulnerability has been resolved:
KVM: x86: Fix shadow paging use-after-free due to unexpected GFN
The shadow MMU computes GFNs for direct shadow pages using sp->gfn plus the SPTE index. This assumption breaks for shadow paging if the guest page tables are modified between VM entries (similar to commit aad885e77496, "KVM: x86/mmu: Drop/zap existing present SPTE even when creating an MMIO SPTE", 2026-03-27). The flow is as follows:
- a PDE is installed for a 2MB mapping, and a page in that area is accessed. KVM creates a kvmmmupage consisting of 512 4KB pages; the kvmmmupage is marked by FNAME(fetch) as direct-mapped because the guest's mapping is a huge page (and thus contiguous).
- the PDE mapping is changed from outside the guest.
- the guest accesses another page in the same 2MB area. KVM installs a new leaf SPTE and rmap entry; the SPTE uses the "correct" GFN (i.e. based on the new mapping, as changed in the previous step) but that GFN is outside of the [sp->gfn, sp->gfn + 511] range; therefore the rmap entry cannot be found and removed when the kvmmmupage is zapped.
- the memslot that covers the first 2MB mapping is deleted, and the kvmmmupage for the now-invalid GPA is zapped. However, rmapremove() only looks at the [sp->gfn, sp->gfn + 511] range established in step 1, and fails to find the rmap entry that was recorded by step 3.
- any operation that causes an rmap walk for the same page accessed by step 3 then walks a stale rmap and dereferences a freed kvmmmupage. This includes dirty logging or MMU notifier invalidations (e.g., from MADVDONTNEED).
The underlying issue is that KVM's walking of shadow PTEs assumes that if a SPTE is present when KVM wants to install a non-leaf SPTE, then the existing kvmmmupage must be for the correct gfn. Because the only way for the gfn to be wrong is if KVM messed up and failed to zap a SPTE... which shouldn't happen, but actually only happens in response to a guest write.
That bug dates back literally forever, as even the first version of KVM assumes that the GFN matches and walks into the "wrong" shadow page. However, that was only an imprecision until 2032a93d66fa ("KVM: MMU: Don't allocate gfns page for direct mmu pages") came along.
Fix it by checking for a target gfn mismatch and zapping the existing SPTE. That way the old SP and rmap entries are gone, KVM installs the rmap in the right location, and everyone is happy.
In the Linux kernel, the following vulnerability has been resolved:
KVM: nSVM: Raise #UD if unhandled VMMCALL isn't intercepted by L1
Explicitly synthesize a #UD for VMMCALL if L2 is active, L1 does NOT want to intercept VMMCALL, nestedsvml2tlbflushenabled() is true, and the hypercall is something other than one of the supported Hyper-V hypercalls. When all of the above conditions are met, KVM will intercept VMMCALL but never forward it to L1, i.e. will let L2 make hypercalls as if it were L1.
The TLFS says a whole lot of nothing about this scenario, so go with the architectural behavior, which says that VMMCALL #UDs if it's not intercepted.
Opportunistically do a 2-for-1 stub trade by stub-ifying the new API instead of the helpers it uses. The last remaining "single" stub will soon be dropped as well.
[sean: rewrite changelog and comment, tag for stable, remove defunct stubs]
In the Linux kernel, the following vulnerability has been resolved:
KVM: x86/mmu: Drop/zap existing present SPTE even when creating an MMIO SPTE
When installing an emulated MMIO SPTE, do so after dropping/zapping the existing SPTE (if it's shadow-present). While commit a54aa15c6bda3 was right about it being impossible to convert a shadow-present SPTE to an MMIO SPTE due to a guest write, it failed to account for writes to guest memory that are outside the scope of KVM.
E.g. if host userspace modifies a shadowed gPTE to switch from a memslot to emulted MMIO and then the guest hits a relevant page fault, KVM will install the MMIO SPTE without first zapping the shadow-present SPTE.
------------[ cut here ]------------ isshadowpresentpte(sptep) WARNING: arch/x86/kvm/mmu/mmu.c:484 at markmmiospte+0xb2/0xc0 [kvm], CPU#0: vmxeptstaler/4292 Modules linked in: kvmintel kvm irqbypass CPU: 0 UID: 1000 PID: 4292 Comm: vmxeptstaler Not tainted 7.0.0-rc2-eafebd2d2ab0-sink-vm #319 PREEMPT Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:markmmiospte+0xb2/0xc0 [kvm] Call Trace: <TASK> mmusetspte+0x237/0x440 [kvm] eptpagefault+0x535/0x7f0 [kvm] kvmmmudopagefault+0xee/0x1f0 [kvm] kvmmmupagefault+0x8d/0x620 [kvm] vmxhandleexit+0x18c/0x5a0 [kvmintel] kvmarchvcpuioctlrun+0xc55/0x1c20 [kvm] kvmvcpuioctl+0x2d5/0x980 [kvm] x64sysioctl+0x8a/0xd0 dosyscall64+0xb5/0x730 entrySYSCALL64afterhwframe+0x4b/0x53 RIP: 0033:0x47fa3f </TASK> ---[ end trace 0000000000000000 ]---
Hi,
On Mon, Mar 30, 2026 at 11:34:02AM +0530, Sandipan Roy wrote: Alexander Bulekov(bkov () amazon com) and Fred Griffoul (fgriffo () amazon com) reported a use-after-free in KVM's shadow paging code. Thank you all for finding and handling this issue, including bringing it to oss-security.
Sandipan Roy first brought this to linux-distros on March 10, writing:
On Tue, Mar 10, 2026 at 04:03:41PM +0530, Sandipan Roy wrote: The reporters and maintainers have agreed on an embargo until Sunday March 29, 2026, 16:00 UTC. The Linux kernel security team did not object to extending the embargo period past the documented limit of 14 calendar days to which I replied:
On Thu, Mar 12, 2026 at 06:04:33PM +0100, Solar Designer wrote: We have a problem here: we also have a 14 days maximum on linux-distros, and no one asked us whether we'd be willing to make an exception. As linux-distros list admin, if asked in advance, I would object to this. More precisely, I'd have asked to delay notification to linux-distros until no more than 14 days remain until embargo end.
But what's done, is done. So here I am acknowledging the policy violation and explaining how it happened and why I let it happen. With a precise planned public disclosure date/time only moderately in excess of the usual maximum, and with many other stakeholders involved, I felt it would be counter-productive to insist on public disclosure after at most 14 days per the policy.
Looking at distros list statistics, we previously let the 14 days be exceeded to a similar extent a year ago, in March 2025. Here's my explanation of that previous occasion (also related to Linux kernel):
https://www.openwall.com/lists/oss-security/2025/04/01/6
Here are the statistics (until end of February - I'll add March likely in mid-April like I usually do):
https://oss-security.openwall.org/wiki/mailing-lists/distros/stats
The maximum we had since mid-2023 when Linux Foundation sponsorship started is a little over 20 days, so just like we had this time. This maximum was reached 3 times in these almost 4 years. The rest of cases are at most 15.5 days (on one occasion; the rest are below 15). Prior to mid-2023, things were occasionally a lot worse as I wasn't keeping track of list statistics like I do now.
Alexander