[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86, hvm: Fix issue with user-mode writes to read-only memory.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1217334297 -3600
# Node ID 5fbcbee355e23986326a539a936b68cf3b17f0db
# Parent  eb10a50752bc81ec0f5d16fc0ef958d20ad6a54b
x86, hvm: Fix issue with user-mode writes to read-only memory.

This patch fixes an issue where a guest could get stuck if a write to
memory marked p2m_ram_ro happened from user mode. It would get
misinterpreted as a user-mode page-table write, and the "dummy write"
emulation necessary to skip over the instruction never got done. In
looking into this, I also discovered that the user-mode page-table
check is done in two places, the second (in emulate_map_dest) of which
can never be reached and is just a waste of cycles. Tim Deegan
requested that rather than completely removing that code, I'd leave it
in for debug-builds with an added warning-print.

Signed-off-by: Trolle Selander <trolle.selander@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm/shadow/multi.c |   23 +++++++++++++++++------
 1 files changed, 17 insertions(+), 6 deletions(-)

diff -r eb10a50752bc -r 5fbcbee355e2 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Tue Jul 29 13:11:29 2008 +0100
+++ b/xen/arch/x86/mm/shadow/multi.c    Tue Jul 29 13:24:57 2008 +0100
@@ -3359,7 +3359,7 @@ static int sh_page_fault(struct vcpu *v,
             gdprintk(XENLOG_DEBUG, "guest attempted write to read-only memory"
                      " page. va page=%#lx, mfn=%#lx\n",
                      va & PAGE_MASK, mfn_x(gmfn));
-        goto emulate; /* skip over the instruction */
+        goto emulate_readonly; /* skip over the instruction */
     }
 
     /* In HVM guests, we force CR0.WP always to be set, so that the
@@ -3404,6 +3404,11 @@ static int sh_page_fault(struct vcpu *v,
         goto done;
     }
 
+    /*
+     * Write from userspace to ro-mem needs to jump here to avoid getting
+     * caught by user-mode page-table check above.
+     */
+ emulate_readonly:
     /*
      * We don't need to hold the lock for the whole emulation; we will
      * take it again when we write to the pagetables.
@@ -4644,11 +4649,6 @@ static void *emulate_map_dest(struct vcp
     unsigned long offset;
     void *map = NULL;
 
-    /* We don't emulate user-mode writes to page tables */
-    sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
-    if ( sreg->attr.fields.dpl == 3 )
-        return MAPPING_UNHANDLEABLE;
-
     sh_ctxt->mfn1 = emulate_gva_to_mfn(v, vaddr, sh_ctxt);
     if ( !mfn_valid(sh_ctxt->mfn1) ) 
         return ((mfn_x(sh_ctxt->mfn1) == BAD_GVA_TO_GFN) ?
@@ -4656,6 +4656,17 @@ static void *emulate_map_dest(struct vcp
                 (mfn_x(sh_ctxt->mfn1) == READONLY_GFN) ?
                 MAPPING_SILENT_FAIL : MAPPING_UNHANDLEABLE);
 
+#ifndef NDEBUG
+    /* We don't emulate user-mode writes to page tables */
+    sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
+    if ( sreg->attr.fields.dpl == 3 )
+    {
+        gdprintk(XENLOG_DEBUG, "User-mode write to pagetable reached "
+                 "emulate_map_dest(). This should never happen!\n");
+        return MAPPING_UNHANDLEABLE;
+    }
+#endif
+                
     /* Unaligned writes mean probably this isn't a pagetable */
     if ( vaddr & (bytes - 1) )
         sh_remove_shadows(v, sh_ctxt->mfn1, 0, 0 /* Slow, can fail */ );

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.