Blob Blame History Raw
From 57b3a2ace5c4a78118b372c95f69af4f0585b48d Mon Sep 17 00:00:00 2001
From: Roger Pau Monne <roger.pau@citrix.com>
Date: Mon, 20 Mar 2023 12:08:52 +0100
Subject: [PATCH] x86/shadow: restore dropped check in
 sh_unshadow_for_p2m_change()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

As a result of 241702e064604dbb3e0d9b731aa8f45be448243b the
mfn_valid() check in sh_unshadow_for_p2m_change() was lost.  That
allows sh_remove_shadows() to be called with gfns that have no backing
page, causing an ASSERT to trigger in debug builds or dereferencing an
arbitrary pointer partially under guest control in non-debug builds:

RIP:    e008:[<ffff82d0402dcf2c>] sh_remove_shadows+0x19f/0x722
RFLAGS: 0000000000010246   CONTEXT: hypervisor (d0v2)
[...]
Xen call trace:
   [<ffff82d0402dcf2c>] R sh_remove_shadows+0x19f/0x722
   [<ffff82d0402e28f4>] F arch/x86/mm/shadow/hvm.c#sh_unshadow_for_p2m_change+0xab/0x2b7
   [<ffff82d040311931>] F arch/x86/mm/p2m-pt.c#write_p2m_entry+0x19b/0x4d3
   [<ffff82d0403131b2>] F arch/x86/mm/p2m-pt.c#p2m_pt_set_entry+0x67b/0xa8e
   [<ffff82d040302c92>] F p2m_set_entry+0xcc/0x149
   [<ffff82d040305a50>] F unmap_mmio_regions+0x17b/0x2c9
   [<ffff82d040241e5e>] F do_domctl+0x11f3/0x195e
   [<ffff82d0402c7e10>] F hvm_hypercall+0x5b1/0xa2d
   [<ffff82d0402adc72>] F vmx_vmexit_handler+0x130f/0x1cd5
   [<ffff82d040203602>] F vmx_asm_vmexit_handler+0xf2/0x210

****************************************
Panic on CPU 1:
Assertion 'mfn_valid(gmfn)' failed at arch/x86/mm/shadow/common.c:2203
****************************************

Fix this by restoring the mfn_valid() check in
sh_unshadow_for_p2m_change(), unifying it with the rest of the checks
that are done at the start of the function.

This is XSA-430 / CVE-2022-42335

Fixes: 241702e064 ('x86/shadow: slightly consolidate sh_unshadow_for_p2m_change() (part II)')
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/mm/shadow/hvm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/mm/shadow/hvm.c b/xen/arch/x86/mm/shadow/hvm.c
index 88c3c16322..6de479c008 100644
--- a/xen/arch/x86/mm/shadow/hvm.c
+++ b/xen/arch/x86/mm/shadow/hvm.c
@@ -814,7 +814,8 @@ static void cf_check sh_unshadow_for_p2m_change(
 
     /* Only previously present / valid entries need processing. */
     if ( !(oflags & _PAGE_PRESENT) ||
-         (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt)) )
+         (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt)) ||
+         !mfn_valid(omfn) )
         return;
 
     switch ( level )
-- 
2.40.0