From b7470f8c19bb680ea4f65dacbc46816d9a95b41d Mon Sep 17 00:00:00 2001 From: Sebastian Ene Date: Thu, 28 Aug 2025 07:42:01 +0000 Subject: [PATCH] ANDROID: KVM: Fix ToCToU issue when admitting pages in memcache Use a local copy of the host provided data to prevent a time of check time of use when we give pages to the hypervisor memcache. Bug: 441436872 Change-Id: I548e2721dc324124cf11f56cd3eb497a8600cdd7 Signed-off-by: Sebastian Ene (cherry picked from commit 557d30a13f308c2638dcdc8b77c409a86bb7df9c) Signed-off-by: Lee Jones --- arch/arm64/kvm/hyp/nvhe/mm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index b41112fea09a..b80df7f714d2 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -554,6 +554,7 @@ int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr) return ret; } +/* Note: The caller has to use a local copy of the arg */ static void *admit_host_page(void *arg, unsigned long order) { phys_addr_t p; @@ -613,15 +614,18 @@ int refill_hyp_pool(struct hyp_pool *pool, struct kvm_hyp_memcache *host_mc) unsigned long order; u64 nr_pages; void *p; + struct kvm_hyp_memcache tmp = *host_mc; - while (host_mc->nr_pages) { - order = FIELD_GET(~PAGE_MASK, host_mc->head); + while (tmp.nr_pages) { + order = FIELD_GET(~PAGE_MASK, tmp.head); if (check_shl_overflow(1UL, order, &nr_pages)) return -EINVAL; - p = admit_host_page(host_mc, order); + p = admit_host_page(&tmp, order); if (!p) return -EINVAL; + *host_mc = tmp; + hyp_virt_to_page(p)->order = order; hyp_set_page_refcounted(hyp_virt_to_page(p)); hyp_put_page(pool, p);