From: sashiko-bot@kernel.org
To: "Marco Elver" <elver@google.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH RFC 03/10] KVM: guest_memfd: Avoid conditional mmu_lock acquisition
Date: Thu, 10 Sep 2026 16:42:13 +0000 [thread overview]
Message-ID: <20260910164214.1BAC01F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260910162343.4092060-4-elver@google.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Concurrent memslot unbind in `!file` case bypasses `filemap_invalidate_lock`, causing UAF and unbalanced MMU invalidate.
--
commit 48bb5bc5161f90dfbe496e0e21d2ca910bf0e571
Author: Marco Elver <elver@google.com>
KVM: guest_memfd: Avoid conditional mmu_lock acquisition
This refactors __kvm_gmem_invalidate_start() to check for present bindings
upfront via xa_find(). It eliminates conditional locking inside the loop to
simplify control flow.
> diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
> index b596486d184ca..1983c1e2dba17 100644
> --- a/virt/kvm/guest_memfd.c
> +++ b/virt/kvm/guest_memfd.c
> @@ -124,10 +124,16 @@ static void __kvm_gmem_invalidate_start(struct gmem_file *f, pgoff_t start,
> pgoff_t end,
> enum kvm_gfn_range_filter attr_filter)
> {
[ ... ]
> - unsigned long index;
> + pgoff_t index = start;
> +
> + if (!xa_find(&f->bindings, &index, end - 1, XA_PRESENT))
> + return;
> +
> + KVM_MMU_LOCK(kvm);
> + kvm_mmu_invalidate_start(kvm);
[Severity: High]
This is a pre-existing issue, but does this upfront check introduce a
time-of-check to time-of-use (TOCTOU) window when interacting with a
concurrent memslot unbind?
Looking at kvm_gmem_unbind() in virt/kvm/guest_memfd.c, if a guest_memfd
file is closing (refcount drops to 0), it skips acquiring
filemap_invalidate_lock:
virt/kvm/guest_memfd.c:kvm_gmem_unbind() {
...
if (!file) {
__kvm_gmem_unbind(slot, slot->gmem.file->private_data);
return;
}
...
}
This allows __kvm_gmem_unbind() to call xa_store_range(..., NULL)
concurrently without holding the lock. If the binding is removed
immediately after the new xa_find() check above, the loop in
__kvm_gmem_invalidate_start() won't execute, but the invalidate counter
is already incremented.
Subsequently, in __kvm_gmem_invalidate_end(), if the lockless unbind
causes its xa_find() to return false:
virt/kvm/guest_memfd.c:__kvm_gmem_invalidate_end() {
if (xa_find(&f->bindings, &start, end - 1, XA_PRESENT)) {
KVM_MMU_LOCK(kvm);
kvm_mmu_invalidate_end(kvm);
KVM_MMU_UNLOCK(kvm);
}
}
Could this skip kvm_mmu_invalidate_end() and permanently leak the
mmu_invalidate_in_progress counter, potentially causing all vCPUs to hang
by infinitely retrying in mmu_invalidate_retry()?
> xa_for_each_range(&f->bindings, index, slot, start, end - 1) {
> pgoff_t pgoff = slot->gmem.pgoff;
[ ... ]
> flush |= kvm_mmu_unmap_gfn_range(kvm, &gfn_range);
[Severity: High]
This is also a pre-existing issue, but does yielding here open a race
window that could lead to a use-after-free?
If __kvm_gmem_invalidate_start() is called via a memory failure path
(e.g., kvm_gmem_error_folio() acquiring filemap_invalidate_lock_shared()),
and kvm_gmem_unbind() concurrently skips the lock, the slot could be
removed from f->bindings and freed by kvm_free_memslot().
Since kvm_mmu_unmap_gfn_range() can drop mmu_lock to yield, could the
iterator access a freed slot when it resumes?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260910162343.4092060-1-elver@google.com?part=3
next prev parent reply other threads:[~2026-09-10 16:42 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 16:21 [PATCH RFC 00/10] KVM: Enable Clang Context Analysis Marco Elver
2026-09-10 16:21 ` [PATCH RFC 01/10] KVM: x86/pmu: Acquire SRCU in pmc_is_event_allowed() to protect filter lookup Marco Elver
2026-09-10 16:46 ` Sean Christopherson
2026-09-10 16:21 ` [PATCH RFC 02/10] KVM: Allow reading memslots while holding slots_arch_lock Marco Elver
2026-09-10 16:30 ` Sean Christopherson
2026-09-10 17:11 ` Marco Elver
2026-09-10 17:52 ` Sean Christopherson
2026-09-10 19:05 ` Marco Elver
2026-09-10 16:39 ` sashiko-bot
2026-09-10 16:21 ` [PATCH RFC 03/10] KVM: guest_memfd: Avoid conditional mmu_lock acquisition Marco Elver
2026-09-10 16:42 ` sashiko-bot [this message]
2026-09-10 16:21 ` [PATCH RFC 04/10] KVM: Refactor kvm_handle_hva_range() to avoid conditional mmu_lock Marco Elver
2026-09-10 16:38 ` Sean Christopherson
2026-09-10 16:21 ` [PATCH RFC 05/10] KVM: Refactor kvm_handle_gfn_range() " Marco Elver
2026-09-10 16:21 ` [PATCH RFC 06/10] KVM: Add basic lock context annotations Marco Elver
2026-09-10 16:34 ` sashiko-bot
2026-09-10 16:53 ` Marco Elver
2026-09-10 16:21 ` [PATCH RFC 07/10] KVM: x86: " Marco Elver
2026-09-10 16:21 ` [PATCH RFC 08/10] KVM: Add guarded_by to members in struct kvm Marco Elver
2026-09-10 16:21 ` [PATCH RFC 09/10] KVM: x86: Add guarded_by annotations for kvm_arch, kvm_hv, and ioapic Marco Elver
2026-09-10 16:46 ` sashiko-bot
2026-09-10 16:21 ` [PATCH RFC 10/10] KVM: x86: Enable CONTEXT_ANALYSIS with opt-outs Marco Elver
2026-09-10 16:55 ` [PATCH RFC 00/10] KVM: Enable Clang Context Analysis Sean Christopherson
2026-09-10 19:19 ` Marco Elver
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=20260910164214.1BAC01F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=elver@google.com \
--cc=kvm@vger.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.