From: sashiko-bot@kernel.org
To: "Marc Zyngier" <maz@kernel.org>
Cc: kvmarm@lists.linux.dev, "Oliver Upton" <oupton@kernel.org>,
"Marc Zyngier" <maz@kernel.org>
Subject: Re: [PATCH v2 2/2] KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction
Date: Fri, 14 Aug 2026 10:48:34 +0000 [thread overview]
Message-ID: <20260814104835.642B81F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260814103230.858578-3-maz@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Reading KVM stage-2 debugfs files after `mmu_notifier_release` causes a NULL pointer dereference or Use-After-Free (UAF).
--
--- Patch [2]: [PATCH v2 2/2] KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction ---
commit 0e0fd6e2861a90f62fede091e967d2714a276ba0
Author: Marc Zyngier <maz@kernel.org>
Subject: KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction
This commit prevents the early freeing of the shadow stage-2 MMU container
structures from kvm_arch_flush_shadow_all(). It introduces a separate
destructor invoked during VM teardown, while keeping the page table freeing
in the original flush callback.
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 99cd2ea61a220..db1824067dbdf 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
[ ... ]
> @@ -56,6 +56,27 @@ int kvm_init_nested(struct kvm *kvm)
> return kvm->arch.nested_mmus ? 0 : -ENOMEM;
> }
>
> +static void kvm_uninit_shadow_stage2_mmu(struct kvm *kvm)
> +{
> + for (int i = 0; i < kvm->arch.nested_mmus_size; i++) {
> + struct kvm_s2_mmu *mmu = kvm->arch.nested_mmus[i];
> +
> + if (!WARN_ON(atomic_read(&mmu->refcnt)))
> + kvm_free_stage2_pgd(mmu);
[Severity: High]
This is a pre-existing issue, but does reading the KVM stage-2 debugfs files
after mmu_notifier_release cause a NULL pointer dereference or use-after-free?
While this patch prevents the use-after-free of the mmu container itself, it
appears mmu->pgt is still vulnerable. When a process exits,
mmu_notifier_release triggers kvm_arch_flush_shadow_all(), which calls down
to kvm_free_stage2_pgd().
kvm_free_stage2_pgd() sets mmu->pgt to NULL and frees the page table
structure:
arch/arm64/kvm/mmu.c:kvm_free_stage2_pgd() {
write_lock(&kvm->mmu_lock);
pgt = mmu->pgt;
if (pgt) {
mmu->pgd_phys = 0;
mmu->pgt = NULL;
...
}
...
write_unlock(&kvm->mmu_lock);
if (pgt) {
kvm_stage2_destroy(pgt);
kfree(pgt);
}
}
However, the KVM VM file descriptor and its debugfs dentries can remain alive.
If a process holding the VM fd reads debugfs files like ipa_range or
stage2_levels, functions like kvm_pgtable_debugfs_open() or
kvm_ptdump_parser_create() will read mmu->pgt without holding kvm->mmu_lock:
arch/arm64/kvm/ptdump.c:kvm_ptdump_parser_create() {
struct kvm_pgtable *pgtable = mmu->pgt;
...
ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
...
}
Could a concurrent read of mmu->pgt either dereference a NULL pointer, or
pass a soon-to-be-freed page table pointer to the seq_file show callbacks
such as kvm_pgtable_range_show()?
> + }
> +}
> +
> +void kvm_destroy_nested(struct kvm *kvm)
> +{
> + kvm_uninit_shadow_stage2_mmu(kvm);
> +
> + for (int i = 0; i < kvm->arch.nested_mmus_size; i+= S2_MMU_PER_VCPU)
> + kvfree(kvm->arch.nested_mmus[i]);
> +
> + kvm->arch.nested_mmus_size = 0;
> + kvfree(kvm->arch.nested_mmus);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260814103230.858578-1-maz@kernel.org?part=2
prev parent reply other threads:[~2026-08-14 10:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 10:32 [PATCH v2 0/2] KVM: arm64: nv: Shadow S2 life-cycle fixes Marc Zyngier
2026-08-14 10:32 ` [PATCH v2 1/2] KVM: arm64: nv: Fix life cycle of the nested_mmus array Marc Zyngier
2026-08-14 11:34 ` sashiko-bot
2026-08-14 10:32 ` [PATCH v2 2/2] KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction Marc Zyngier
2026-08-14 10:48 ` sashiko-bot [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814104835.642B81F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.