From: Jan Beulich Subject: Arm: adjust locking in p2m_get_page_from_gfn() In order to safely acquire a reference for a foreign page mapping, the P2M lock needs to be held until we have the reference in hand (or getting one failed). Otherwise the page can change P2M type and ownership in between. This is CVE-2025-58145 / part of XSA-473. Fixes: 9486a8d07ba8 ("xen/arm: Handle remove foreign mapping") Signed-off-by: Jan Beulich Reviewed-by: Julien Grall --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -53,18 +53,22 @@ mfn_t p2m_lookup(struct domain *d, gfn_t struct page_info *p2m_get_page_from_gfn(struct domain *d, gfn_t gfn, p2m_type_t *t) { + struct p2m_domain *p2m = p2m_get_hostp2m(d); struct page_info *page; p2m_type_t p2mt; - mfn_t mfn = p2m_lookup(d, gfn, &p2mt); + mfn_t mfn; + + p2m_read_lock(p2m); + mfn = p2m_get_entry(p2m, gfn, &p2mt, NULL, NULL, NULL); if ( t ) *t = p2mt; - if ( !p2m_is_any_ram(p2mt) ) - return NULL; - - if ( !mfn_valid(mfn) ) + if ( !p2m_is_any_ram(p2mt) || !mfn_valid(mfn) ) + { + p2m_read_unlock(p2m); return NULL; + } page = mfn_to_page(mfn); @@ -76,6 +80,8 @@ struct page_info *p2m_get_page_from_gfn( { const struct domain *fdom = page_get_owner_and_reference(page); + p2m_read_unlock(p2m); + if ( fdom ) { if ( fdom != d ) @@ -86,6 +92,8 @@ struct page_info *p2m_get_page_from_gfn( return NULL; } + p2m_read_unlock(p2m); + return get_page(page, d) ? page : NULL; }