mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: Fix shadow paging use-after-free due to unexpected GFN
@ 2026-05-03 20:10 Paolo Bonzini
  2026-05-05 10:13 ` stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN" Paolo Bonzini
  0 siblings, 1 reply; 7+ messages in thread
From: Paolo Bonzini @ 2026-05-03 20:10 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Sean Christopherson, Alexander Bulekov, Fred Griffoul, stable

From: Sean Christopherson <seanjc@google.com>

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 kvm_mmu_page consisting of 512 4KB pages;
  the kvm_mmu_page 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 kvm_mmu_page
  is zapped.

- the memslot that covers the first 2MB mapping is deleted, and the
  kvm_mmu_page for the now-invalid GPA is zapped.  However, rmap_remove()
  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 kvm_mmu_age.
  This includes dirty logging or MMU notifier invalidations (e.g., from
  MADV_DONTNEED).

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 kvm_mmu_page 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.

Fixes: 2032a93d66fa ("KVM: MMU: Don't allocate gfns page for direct mmu pages")
Fixes: 6aa8b732ca01 ("kvm: userspace interface")
Reported-by: Alexander Bulekov <bkov@amazon.com>
Reported-by: Fred Griffoul <fgriffo@amazon.co.uk>
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/mmu/mmu.c | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 24fbc9ea502a..892246204435 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -182,6 +182,8 @@ static struct kmem_cache *pte_list_desc_cache;
 struct kmem_cache *mmu_page_header_cache;
 
 static void mmu_spte_set(u64 *sptep, u64 spte);
+static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
+			    u64 *spte, struct list_head *invalid_list);
 
 struct kvm_mmu_role_regs {
 	const unsigned long cr0;
@@ -1287,19 +1289,6 @@ static void drop_spte(struct kvm *kvm, u64 *sptep)
 		rmap_remove(kvm, sptep);
 }
 
-static void drop_large_spte(struct kvm *kvm, u64 *sptep, bool flush)
-{
-	struct kvm_mmu_page *sp;
-
-	sp = sptep_to_sp(sptep);
-	WARN_ON_ONCE(sp->role.level == PG_LEVEL_4K);
-
-	drop_spte(kvm, sptep);
-
-	if (flush)
-		kvm_flush_remote_tlbs_sptep(kvm, sptep);
-}
-
 /*
  * Write-protect on the specified @sptep, @pt_protect indicates whether
  * spte write-protection is caused by protecting shadow page table.
@@ -2466,7 +2455,8 @@ static struct kvm_mmu_page *kvm_mmu_get_child_sp(struct kvm_vcpu *vcpu,
 {
 	union kvm_mmu_page_role role;
 
-	if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
+	if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep) &&
+	    spte_to_child_sp(*sptep) && spte_to_child_sp(*sptep)->gfn == gfn)
 		return ERR_PTR(-EEXIST);
 
 	role = kvm_mmu_child_role(sptep, direct, access);
@@ -2544,13 +2534,16 @@ static void __link_shadow_page(struct kvm *kvm,
 
 	BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK);
 
-	/*
-	 * If an SPTE is present already, it must be a leaf and therefore
-	 * a large one.  Drop it, and flush the TLB if needed, before
-	 * installing sp.
-	 */
-	if (is_shadow_present_pte(*sptep))
-		drop_large_spte(kvm, sptep, flush);
+	if (is_shadow_present_pte(*sptep)) {
+		struct kvm_mmu_page *parent_sp;
+		LIST_HEAD(invalid_list);
+
+		parent_sp = sptep_to_sp(sptep);
+		WARN_ON_ONCE(parent_sp->role.level == PG_LEVEL_4K);
+
+		mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list);
+		kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, true);
+	}
 
 	spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));
 
-- 
2.54.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-05-03 20:10 [PATCH] KVM: x86: Fix shadow paging use-after-free due to unexpected GFN Paolo Bonzini
@ 2026-05-05 10:13 ` Paolo Bonzini
  2026-05-29  8:37   ` Bjoern Doebel
  0 siblings, 1 reply; 7+ messages in thread
From: Paolo Bonzini @ 2026-05-05 10:13 UTC (permalink / raw)
  To: linux-kernel, kvm
  Cc: Sean Christopherson, Alexander Bulekov, Fred Griffoul, stable

I have started sending out backports for stable kernels up to 6.1.  For 
5.10 and 5.15 I have identified the required patches and backported 
them, but I haven't tested them yet.

I'll get to testing and sending them out, but it will take a while; if 
anybody wants to help testing, I can provide my tentative patches.

This is the list for 5.15:

     27a59d57f073 KVM: x86/mmu: Use a bool for direct
     86938ab6925b KVM: x86/mmu: Stop passing "direct" to mmu_alloc_root()
     2e65e842c57d KVM: x86/mmu: Derive shadow MMU page role from parent
     7f49777550e5 KVM: x86/mmu: Always pass 0 for @quadrant when gptes
                  are 8 bytes
     0cd8dc739833 KVM: x86/mmu: pull call to drop_large_spte() into
                  __link_shadow_page()
     0cb2af2ea66a KVM: x86: Fix shadow paging use-after-free due to
                  unexpected GFN


and the longer one for 5.10:

     b37233c911cb KVM: x86/mmu: Capture 'mmu' in a local variable when
                  allocating roots
     ba0a194ffbfb KVM: x86/mmu: Allocate the lm_root before allocating
                  PAE roots
     748e52b9b736 KVM: x86/mmu: Allocate pae_root and lm_root pages in
                  dedicated helper
     6e6ec5848574 KVM: x86/mmu: Ensure MMU pages are available when
                  allocating roots
     27a59d57f073 KVM: x86/mmu: Use a bool for direct
     86938ab6925b KVM: x86/mmu: Stop passing "direct" to mmu_alloc_root()
     03fffc5493c8 KVM: x86/mmu: Refactor shadow walk in __direct_map() to
                  reduce indentation
     f81602958c11 KVM: X86: Fix missed remote tlb flush in
                  rmap_write_protect()
     65855ed8b034 KVM: X86: Synchronize the shadow pagetable before link
                  it
     2e65e842c57d KVM: x86/mmu: Derive shadow MMU page role from parent
     7f49777550e5 KVM: x86/mmu: Always pass 0 for @quadrant when gptes
                  are 8 bytes
     6e0918aec49a KVM: x86/mmu: Check PDPTRs before allocating PAE roots
     0cd8dc739833 KVM: x86/mmu: pull call to drop_large_spte() into
                  __link_shadow_page()
     0cb2af2ea66a KVM: x86: Fix shadow paging use-after-free due to
                  unexpected GFN

Paolo

On Sun, May 3, 2026 at 10:10 PM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> From: Sean Christopherson <seanjc@google.com>
>
> 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 kvm_mmu_page consisting of 512 4KB pages;
>   the kvm_mmu_page 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 kvm_mmu_page
>   is zapped.
>
> - the memslot that covers the first 2MB mapping is deleted, and the
>   kvm_mmu_page for the now-invalid GPA is zapped.  However, rmap_remove()
>   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 kvm_mmu_age.
>   This includes dirty logging or MMU notifier invalidations (e.g., from
>   MADV_DONTNEED).
>
> 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 kvm_mmu_page 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.
>
> Fixes: 2032a93d66fa ("KVM: MMU: Don't allocate gfns page for direct mmu pages")
> Fixes: 6aa8b732ca01 ("kvm: userspace interface")
> Reported-by: Alexander Bulekov <bkov@amazon.com>
> Reported-by: Fred Griffoul <fgriffo@amazon.co.uk>
> Cc: stable@vger.kernel.org
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  arch/x86/kvm/mmu/mmu.c | 35 ++++++++++++++---------------------
>  1 file changed, 14 insertions(+), 21 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 24fbc9ea502a..892246204435 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -182,6 +182,8 @@ static struct kmem_cache *pte_list_desc_cache;
>  struct kmem_cache *mmu_page_header_cache;
>
>  static void mmu_spte_set(u64 *sptep, u64 spte);
> +static int mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
> +                           u64 *spte, struct list_head *invalid_list);
>
>  struct kvm_mmu_role_regs {
>         const unsigned long cr0;
> @@ -1287,19 +1289,6 @@ static void drop_spte(struct kvm *kvm, u64 *sptep)
>                 rmap_remove(kvm, sptep);
>  }
>
> -static void drop_large_spte(struct kvm *kvm, u64 *sptep, bool flush)
> -{
> -       struct kvm_mmu_page *sp;
> -
> -       sp = sptep_to_sp(sptep);
> -       WARN_ON_ONCE(sp->role.level == PG_LEVEL_4K);
> -
> -       drop_spte(kvm, sptep);
> -
> -       if (flush)
> -               kvm_flush_remote_tlbs_sptep(kvm, sptep);
> -}
> -
>  /*
>   * Write-protect on the specified @sptep, @pt_protect indicates whether
>   * spte write-protection is caused by protecting shadow page table.
> @@ -2466,7 +2455,8 @@ static struct kvm_mmu_page *kvm_mmu_get_child_sp(struct kvm_vcpu *vcpu,
>  {
>         union kvm_mmu_page_role role;
>
> -       if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
> +       if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep) &&
> +           spte_to_child_sp(*sptep) && spte_to_child_sp(*sptep)->gfn == gfn)
>                 return ERR_PTR(-EEXIST);
>
>         role = kvm_mmu_child_role(sptep, direct, access);
> @@ -2544,13 +2534,16 @@ static void __link_shadow_page(struct kvm *kvm,
>
>         BUILD_BUG_ON(VMX_EPT_WRITABLE_MASK != PT_WRITABLE_MASK);
>
> -       /*
> -        * If an SPTE is present already, it must be a leaf and therefore
> -        * a large one.  Drop it, and flush the TLB if needed, before
> -        * installing sp.
> -        */
> -       if (is_shadow_present_pte(*sptep))
> -               drop_large_spte(kvm, sptep, flush);
> +       if (is_shadow_present_pte(*sptep)) {
> +               struct kvm_mmu_page *parent_sp;
> +               LIST_HEAD(invalid_list);
> +
> +               parent_sp = sptep_to_sp(sptep);
> +               WARN_ON_ONCE(parent_sp->role.level == PG_LEVEL_4K);
> +
> +               mmu_page_zap_pte(kvm, parent_sp, sptep, &invalid_list);
> +               kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, true);
> +       }
>
>         spte = make_nonleaf_spte(sp->spt, sp_ad_disabled(sp));
>
> --
> 2.54.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-05-05 10:13 ` stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN" Paolo Bonzini
@ 2026-05-29  8:37   ` Bjoern Doebel
  2026-06-20  5:40     ` Paolo Bonzini
  0 siblings, 1 reply; 7+ messages in thread
From: Bjoern Doebel @ 2026-05-29  8:37 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Bjoern Doebel, linux-kernel, kvm, Sean Christopherson,
	Alexander Bulekov, Fred Griffoul, stable, zcgao

Hi Paolo,

On Tue, May 05, 2026 at 12:13:34PM +0200, Paolo Bonzini wrote:
> I'll get to testing and sending them out, but it will take a while; if
> anybody wants to help testing, I can provide my tentative patches.

took us a while, but if you are still looking for help, my friend Nathan
and I would volunteer to test these in the context of Amazon Linux.

Best,
Bjoern




Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-05-29  8:37   ` Bjoern Doebel
@ 2026-06-20  5:40     ` Paolo Bonzini
  2026-06-25 22:04       ` Nathan Gao
                         ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Paolo Bonzini @ 2026-06-20  5:40 UTC (permalink / raw)
  To: Bjoern Doebel
  Cc: linux-kernel, kvm, Sean Christopherson, Alexander Bulekov,
	Fred Griffoul, stable, zcgao

On Fri, May 29, 2026 at 10:39 AM Bjoern Doebel <doebel@amazon.de> wrote:
>
> Hi Paolo,
>
> On Tue, May 05, 2026 at 12:13:34PM +0200, Paolo Bonzini wrote:
> > I'll get to testing and sending them out, but it will take a while; if
> > anybody wants to help testing, I can provide my tentative patches.
>
> took us a while, but if you are still looking for help, my friend Nathan
> and I would volunteer to test these in the context of Amazon Linux.

Thanks,

I placed everything in the linux-5.10.y and linux-5.15.y branches of
https://git.kernel.org/pub/scm/virt/kvm/kvm.git, adding also a couple
more issues that were fixed in the last merge window.

Paolo


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-06-20  5:40     ` Paolo Bonzini
@ 2026-06-25 22:04       ` Nathan Gao
  2026-06-30  2:33       ` Nathan Gao
  2026-06-30 22:37       ` Nathan Gao
  2 siblings, 0 replies; 7+ messages in thread
From: Nathan Gao @ 2026-06-25 22:04 UTC (permalink / raw)
  To: pbonzini; +Cc: bkov, doebel, fgriffo, kvm, linux-kernel, seanjc, stable, zcgao

Thanks Paolo! I tested these in the context of Amazon Linux, carrying the
series as a downstream patch set on top of our 5.10 and 5.15 trees, as
follows.

Test setup
- Trees: Amazon Linux 5.10 and 5.15, with the backports applied as
  downstream patches. (For 5.10, applied a83e50d86^..d3d0e6688; for 5.15,
  applied 4db658c99^..1ab8cd246)
- For each tree we ran with EPT enabled and disabled, i.e.
    sudo rmmod kvm_intel && sudo modprobe kvm_intel ept=0
  and confirmed via /sys/module/kvm_intel/parameters/ept.
- Tested with AWS EC2 c5.metal.

Tests
- KVM selftests: make -C tools/testing/selftests/kvm run_tests
- kvm-unit-tests: https://www.linux-kvm.org/page/KVM-unit-tests

For each (tree x EPT setting) we collected results before and after
applying the backport and compared them.

Results
- No regressions. On both 5.10 and 5.15, and with EPT on and off, the
  test outcomes are the same before and after the backport.
- kvm-unit-tests output was identical before vs. after.
- The KVM selftest verdicts (ok/not ok) were identical before vs. after.
  The handful of failing tests are pre-existing on our baseline and
  unrelated to the MMU change (e.g. debug_regs, vmx_pmu_msrs_test, a
  memslot_perf_test timeout, etc.).

So from these tests, the backport looks good. Please let me know if
there are any other tests I can help with. 

Tested-by: Nathan Gao <zcgao@amazon.com>

Thanks,
Nathan Gao

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-06-20  5:40     ` Paolo Bonzini
  2026-06-25 22:04       ` Nathan Gao
@ 2026-06-30  2:33       ` Nathan Gao
  2026-06-30 22:37       ` Nathan Gao
  2 siblings, 0 replies; 7+ messages in thread
From: Nathan Gao @ 2026-06-30  2:33 UTC (permalink / raw)
  To: pbonzini; +Cc: bkov, doebel, fgriffo, kvm, linux-kernel, seanjc, stable, zcgao

Hi Paolo,

We found a regression from the backported series. Below is the reproducing
steps and the data we captured is from kvm/kvm.git linux-5.10.y branch, HEAD commit
d3d0e6688c. 5.15 may also have the same issue but I haven't got chance to test yet.

Reproducer
----------
Launch kvm.git linux-5.10.y kernel build with qemu. Then inside the guest, 
launch another qemu:

  qemu-system-x86_64 \
    -smp 8 -m 4G -enable-kvm -cpu host,vmx=on \
    -machine q35,kernel-irqchip=split -display none \
    -kernel <any-bzImage> -initrd <any-initrd> \
    -nic user -serial mon:stdio -append "console=ttyS0 nokaslr"

WARNs fire during boot on kvm_page_track_flush_slot. Sending SIGKILL to the
qemu process afterward triggers another WARN on kvm_mmu_notifier_release.
The timing requirement is low. 1 or 2 try will produce the issue. 

The issue does NOT reproduce on the pre-backport baseline
(v5.10.254).

Traces (5.10.254+, kvm/kvm.git linux-5.10.y)
---------------------------------------------

1. During boot:

[   27.638425] ------------[ cut here ]------------
[   27.639115] WARNING: CPU: 14 PID: 2193 at arch/x86/kvm/mmu/mmu.c:5471 kvm_mmu_zap_all_fast+0x12e/0x180
[   27.640421] Modules linked in:
[   27.640869] CPU: 14 PID: 2193 Comm: qemu-system-x86 Not tainted 5.10.254+ #5
[   27.641884] Hardware name: Red Hat KVM, BIOS 1.11.0-2.amzn2 04/01/2014
[   27.642808] RIP: 0010:kvm_mmu_zap_all_fast+0x12e/0x180
[   27.643536] Code: e8 47 fb ff ff 44 03 6c 24 04 84 c0 0f 85 47 ff ff ff 48 89 e8 48 89 eb 48 8b 6d 08 4c 39 f8 0f 85 45 ff ff ff e9 54 ff ff ff <0f> 0b eb e4 65 8b 05 af ad fa 7e 89 c0 48 0f a3 05 4d fe 2f 02 0f
[   27.646159] RSP: 0018:ffffc900006dbbc8 EFLAGS: 00010202
[   27.646900] RAX: 0000000000000000 RBX: ffff8881060dcb28 RCX: 0000000000000000
[   27.647910] RDX: 0000000000000000 RSI: 0000000000000010 RDI: ffff888101f716b8
[   27.648888] RBP: ffff8881060dc7e0 R08: 00000009d5d7051e R09: ffff888101f716b0
[   27.649907] R10: ffffc900006dbc18 R11: 0000000000000008 R12: ffffc90000691000
[   27.650910] R13: 0000000000000000 R14: ffffc90000699a80 R15: ffffc90000699a70
[   27.651921] FS:  00007f8aa4a3a700(0000) GS:ffff888627d80000(0000) knlGS:0000000000000000
[   27.653028] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   27.653852] CR2: 00007f8a9c40b000 CR3: 000000010709c003 CR4: 0000000000772ee0
[   27.654858] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   27.655856] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   27.656837] PKRU: 55555554
[   27.657219] Call Trace:
[   27.657578]  kvm_page_track_flush_slot+0x51/0x90
[   27.658270]  kvm_set_memslot+0x179/0x660
[   27.658831]  kvm_delete_memslot+0x68/0xe0
[   27.659403]  __kvm_set_memory_region+0x391/0x560
[   27.660066]  ? rcuwait_wake_up+0x22/0x30
[   27.660611]  ? kvm_vcpu_wake_up+0x15/0x40
[   27.661169]  ? kvm_vcpu_kick+0xf/0x60
[   27.661718]  ? __check_object_size+0x73/0x1b0
[   27.662342]  ? _copy_to_user+0x1c/0x30
[   27.662879]  kvm_set_memory_region+0x26/0x40
[   27.663489]  kvm_vm_ioctl+0x7e5/0xb80
[   27.664020]  ? handle_mm_fault+0x1113/0x1730
[   27.664616]  __x64_sys_ioctl+0x8f/0xd0
[   27.665145]  do_syscall_64+0x33/0x40
[   27.665691]  entry_SYSCALL_64_after_hwframe+0x67/0xd1
[   27.666419] RIP: 0033:0x7f8aaa70f9a7
[   27.666932] Code: 00 00 90 48 8b 05 d9 04 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a9 04 2c 00 f7 d8 64 89 01 48
[   27.669508] RSP: 002b:00007f8aa4a39248 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[   27.670600] RAX: ffffffffffffffda RBX: 000055abe9c26eb0 RCX: 00007f8aaa70f9a7
[   27.671604] RDX: 00007f8aa4a392b0 RSI: 000000004020ae46 RDI: 000000000000000b
[   27.672598] RBP: 000055abe9c24980 R08: 0000000000000007 R09: fffffffffffffe78
[   27.673577] R10: 00007f8a9c41e600 R11: 0000000000000246 R12: 00007f8aa4a392b0
[   27.674701] R13: 0000000001000000 R14: 0000000000000000 R15: 0000000000000000
[   27.675703] ---[ end trace ff19449f37382c4a ]---

2. On SIGKILL:

[   47.572967] ------------[ cut here ]------------
[   47.573762] WARNING: CPU: 13 PID: 2192 at arch/x86/kvm/mmu/mmu.c:5785 kvm_mmu_zap_all+0x82/0xf0
[   47.575104] Modules linked in:
[   47.575583] CPU: 13 PID: 2192 Comm: qemu-system-x86 Tainted: G        W         5.10.254+ #5
[   47.576851] Hardware name: Red Hat KVM, BIOS 1.11.0-2.amzn2 04/01/2014
[   47.577902] RIP: 0010:kvm_mmu_zap_all+0x82/0xf0
[   47.578596] Code: ef e8 f2 7f ff ff 84 c0 75 db 48 89 ef e8 b6 18 0d 00 85 c0 75 cf 48 89 d8 48 89 de 48 8b 1b 49 39 c5 74 16 f6 46 35 08 74 cc <0f> 0b 48 89 d8 48 89 de 48 8b 1b 49 39 c5 75 ea 48 8b 44 24 08 4c
[   47.581340] RSP: 0018:ffffc90000827c20 EFLAGS: 00010202
[   47.582173] RAX: ffff8881084be930 RBX: ffff8881084be690 RCX: 0000000000000000
[   47.583232] RDX: 0000000080000000 RSI: ffff8881084be930 RDI: ffffc90000691000
[   47.584293] RBP: ffffc90000691000 R08: 000000000003d0e0 R09: ffff888101f71848
[   47.585364] R10: ffff8881070c8c10 R11: ffff8881070c8800 R12: ffffc90000827c28
[   47.586436] R13: ffffc90000699a70 R14: ffff8881020c4bb8 R15: ffff888101436078
[   47.587476] FS:  0000000000000000(0000) GS:ffff888627d40000(0000) knlGS:0000000000000000
[   47.588629] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   47.589456] CR2: 00007f91360231a0 CR3: 000000010709c004 CR4: 0000000000772ee0
[   47.590527] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   47.591548] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   47.592574] PKRU: 55555554
[   47.592973] Call Trace:
[   47.593346]  kvm_mmu_notifier_release+0x26/0x60
[   47.594046]  __mmu_notifier_release+0x6e/0x1c0
[   47.594706]  exit_mmap+0x14c/0x190
[   47.595221]  ? __ksm_exit+0x112/0x1b0
[   47.595752]  ? kmem_cache_free+0x39c/0x400
[   47.596342]  ? kmem_cache_free+0x39c/0x400
[   47.596931]  ? __ksm_exit+0x112/0x1b0
[   47.597463]  mmput+0x50/0x130
[   47.597938]  do_exit+0x31b/0xb70
[   47.598418]  ? __remove_hrtimer+0x39/0x70
[   47.599005]  ? hrtimer_try_to_cancel+0xb2/0xf0
[   47.599649]  do_group_exit+0x3a/0xa0
[   47.600199]  get_signal+0x145/0x890
[   47.600722]  arch_do_signal_or_restart+0xad/0x270
[   47.601415]  exit_to_user_mode_prepare+0x115/0x190
[   47.602150]  syscall_exit_to_user_mode+0x22/0x140
[   47.602831]  entry_SYSCALL_64_after_hwframe+0x67/0xd1
[   47.603556] RIP: 0033:0x7f8aaa70f9a7
[   47.604078] Code: Unable to access opcode bytes at RIP 0x7f8aaa70f97d.
[   47.605051] RSP: 002b:00007f8aa523a6c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[   47.606191] RAX: fffffffffffffffc RBX: 0000000000000001 RCX: 00007f8aaa70f9a7
[   47.607200] RDX: 0000000000000000 RSI: 000000000000ae80 RDI: 000000000000000c
[   47.608208] RBP: 000055abc42a5220 R08: 0000000000000000 R09: 000055abc42a9410
[   47.609212] R10: 0000000000000001 R11: 0000000000000246 R12: 000055abe9c36d5e
[   47.610267] R13: 0000000000000000 R14: 00007f8ab0169000 R15: 000055abe9c36cc0
[   47.611299] ---[ end trace ff19449f37382c4e ]---



I am withdrawing my earlier Tested-by after this finding.
The KVM selftests and kvm-unit-tests are limited, which is why they did not catch it.

Please let me know if there is additional information I can provide,
or if you would like me to test a v2.

Thanks,
Nathan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN"
  2026-06-20  5:40     ` Paolo Bonzini
  2026-06-25 22:04       ` Nathan Gao
  2026-06-30  2:33       ` Nathan Gao
@ 2026-06-30 22:37       ` Nathan Gao
  2 siblings, 0 replies; 7+ messages in thread
From: Nathan Gao @ 2026-06-30 22:37 UTC (permalink / raw)
  To: pbonzini
  Cc: bkov, doebel, fgriffo, kvm, linux-kernel, seanjc, stable, zcgao,
	awallace

We identified commit a955cad84cda ("KVM: x86/mmu: Retry page fault if root is invalidated by memslot update")
may be the missing piece. After backporting this patch, it's no longer reproducible after 20 consecutive attempts.  

Thanks to Nicolas Saenz Julienne <nsaenz@amazon.com> who found this regression initially.

Best,
Nathan

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-30 22:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-03 20:10 [PATCH] KVM: x86: Fix shadow paging use-after-free due to unexpected GFN Paolo Bonzini
2026-05-05 10:13 ` stable backports for "KVM: x86: Fix shadow paging use-after-free due to unexpected GFN" Paolo Bonzini
2026-05-29  8:37   ` Bjoern Doebel
2026-06-20  5:40     ` Paolo Bonzini
2026-06-25 22:04       ` Nathan Gao
2026-06-30  2:33       ` Nathan Gao
2026-06-30 22:37       ` Nathan Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®