[PATCH] KVM: pfncache: Fix uhva validity check in kvm_gpc_is_valid_len()
From: phind . uet
Date: Mon Mar 09 2026 - 03:59:21 EST
From: Nguyen Dinh Phi <phind.uet@xxxxxxxxx>
In kvm_gpc_is_valid_len(), if the GPA is an error GPA, the function uses
uhva to calculate the page offset. However, if uhva is invalid, its value
can still be page-aligned (for example, PAGE_OFFSET) and this function will
still return true.
An invalid uhva could lead to incorrect offset calculations and potentially
trigger a WARN_ON_ONCE in __kvm_gpc_refresh().
Fixing it by adding an additional check for uhva.
Signed-off-by: Nguyen Dinh Phi <phind.uet@xxxxxxxxx>
Reported-by: syzbot+cde12433b6c56f55d9ed@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=cde12433b6c56f55d9ed
---
virt/kvm/pfncache.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
index 728d2c1b488a..707ead0a096c 100644
--- a/virt/kvm/pfncache.c
+++ b/virt/kvm/pfncache.c
@@ -60,8 +60,16 @@ void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start,
static bool kvm_gpc_is_valid_len(gpa_t gpa, unsigned long uhva,
unsigned long len)
{
- unsigned long offset = kvm_is_error_gpa(gpa) ? offset_in_page(uhva) :
- offset_in_page(gpa);
+ unsigned long offset;
+
+ if (kvm_is_error_gpa(gpa)) {
+ if (kvm_is_error_hva(uhva))
+ return false;
+
+ offset = offset_in_page(uhva);
+ } else {
+ offset = offset_in_page(gpa);
+ }
/*
* The cached access must fit within a single page. The 'len' argument
--
2.43.0