From: sashiko-bot@kernel.org
To: "Karl Mehltretter" <kmehltretter@gmail.com>
Cc: "Oliver Upton" <oupton@kernel.org>,
"Marc Zyngier" <maz@kernel.org>,
kvmarm@lists.linux.dev
Subject: Re: [PATCH v2] KVM: arm64: nv: Keep the shadow S2 MMUs at fixed addresses
Date: Thu, 06 Aug 2026 06:38:59 +0000 [thread overview]
Message-ID: <20260806063900.66A981F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260806062352.93489-1-kmehltretter@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Critical] Deterministic NULL pointer dereference and Use-After-Free race on the `nested_mmus` array after `kvm_arch_flush_shadow_all` executes.
Pre-existing issues:
- [Critical] Deterministic NULL pointer dereference in `get_s2_mmu_nested` when `nested_mmus_size` is 0.
--
--- Patch [1]: [PATCH v2] KVM: arm64: nv: Keep the shadow S2 MMUs at fixed addresses ---
commit 70c0982ec06bd8ebb390c1b7ff665dae83887bb8
Author: Karl Mehltretter <kmehltretter@gmail.com>
KVM: arm64: nv: Keep the shadow S2 MMUs at fixed addresses
This patch turns the nested_mmus array into a fixed-size pointer table
allocated once during VM creation. The S2 MMUs are allocated individually
during vCPU initialization to keep their addresses stable, fixing a
slab-use-after-free issue.
v1: https://lore.kernel.org/r/20260803224405.41468-1-kmehltretter@gmail.com/
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -90,44 +104,44 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
[ ... ]
> for (i = 0; i < S2_MMU_PER_VCPU; i++) {
> mmu = kzalloc_obj(*mmu, GFP_KERNEL_ACCOUNT);
> if (!mmu) {
> ret = -ENOMEM;
> goto err_free_mmus;
> }
>
> ret = init_nested_s2_mmu(kvm, mmu);
> if (ret) {
> kfree(mmu);
> goto err_free_vncr;
> }
>
> kvm->arch.nested_mmus[kvm->arch.nested_mmus_size + i] = mmu;
[Severity: Critical]
Can this lead to a NULL pointer dereference or use-after-free?
The patch shifts the allocation of kvm->arch.nested_mmus to VM creation in
kvm_init_nested(), but kvm_arch_flush_shadow_all() still frees the array and
sets the pointer to NULL and size to 0.
If an unprivileged user process triggers kvm_mmu_notifier_release(), for
example by passing the file descriptor to a child process and exiting,
kvm_arch_flush_shadow_all() will free the array.
A subsequent KVM_ARM_VCPU_INIT ioctl will bypass the size check in
kvm_vcpu_init_nested() because num_mmus is greater than 0 and
nested_mmus_size is 0. It will allocate an MMU and write it directly to
kvm->arch.nested_mmus[kvm->arch.nested_mmus_size + i], which dereferences
the now NULL pointer.
Additionally, since this write happens outside mmu_lock, it could race with
a concurrent kvm_arch_flush_shadow_all() execution and write into freed
memory.
[ ... ]
> @@ -805,7 +819,7 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
> for (i = kvm->arch.nested_mmus_next;
> i < (kvm->arch.nested_mmus_size + kvm->arch.nested_mmus_next);
> i++) {
> - s2_mmu = &kvm->arch.nested_mmus[i % kvm->arch.nested_mmus_size];
> + s2_mmu = kvm->arch.nested_mmus[i % kvm->arch.nested_mmus_size];
>
> if (atomic_read(&s2_mmu->refcnt) == 0)
> break;
> }
[Severity: Critical]
This is a pre-existing issue, but can this lead to a NULL pointer
dereference when nested_mmus_size is 0?
If kvm_arch_flush_shadow_all() executes while a vCPU is active, it sets
kvm->arch.nested_mmus_size to 0.
When the vCPU subsequently enters get_s2_mmu_nested(), lookup_s2_mmu()
evaluates the empty array and returns NULL, assigning NULL to s2_mmu.
The for loop condition i < (0 + next) evaluates to false, causing the loop
to be completely bypassed.
The function then executes BUG_ON(atomic_read(&s2_mmu->refcnt)) just below
this loop, which dereferences the uninitialized or NULL s2_mmu pointer.
This can be reliably triggered by terminating a VM process while it is
executing nested virtualization workloads.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806062352.93489-1-kmehltretter@gmail.com?part=1
next prev parent reply other threads:[~2026-08-06 6:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 6:23 [PATCH v2] KVM: arm64: nv: Keep the shadow S2 MMUs at fixed addresses Karl Mehltretter
2026-08-06 6:38 ` sashiko-bot [this message]
2026-08-06 13:38 ` Wei-Lin Chang
2026-08-06 14:49 ` Wei-Lin Chang
2026-08-06 18:00 ` Karl Mehltretter
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=20260806063900.66A981F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=kmehltretter@gmail.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox