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