]> xenbits.xensource.com Git - xen.git/commitdiff
x86/traps: fix an off-by-one error
authorHongyan Xia <hongyxia@amazon.com>
Thu, 7 May 2020 12:50:23 +0000 (14:50 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 7 May 2020 12:50:23 +0000 (14:50 +0200)
stack++ can go into the next page and unmap_domain_page() will unmap the
wrong one, causing mapcache and memory corruption. Fix.

Signed-off-by: Hongyan Xia <hongyxia@amazon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: 2e3d87cc734a895ef5b486926274a178836b67a9
master date: 2020-05-05 16:13:44 +0100

xen/arch/x86/traps.c

index 8705ec83156afd8a96434e3df91b6c4d1f85f24d..54aca36714500ddcb536aa495baf9d56e3de561f 100644 (file)
@@ -232,6 +232,7 @@ static void compat_show_guest_stack(struct vcpu *v,
                                     int debug_stack_lines)
 {
     unsigned int i, *stack, addr, mask = STACK_SIZE;
+    void *stack_page = NULL;
 
     stack = (unsigned int *)(unsigned long)regs->esp;
     printk("Guest stack trace from esp=%08lx:\n ", (unsigned long)stack);
@@ -254,7 +255,7 @@ static void compat_show_guest_stack(struct vcpu *v,
                 break;
         if ( !vcpu )
         {
-            stack = do_page_walk(v, (unsigned long)stack);
+            stack_page = stack = do_page_walk(v, (unsigned long)stack);
             if ( (unsigned long)stack < PAGE_SIZE )
             {
                 printk("Inaccessible guest memory.\n");
@@ -281,11 +282,10 @@ static void compat_show_guest_stack(struct vcpu *v,
         printk(" %08x", addr);
         stack++;
     }
-    if ( mask == PAGE_SIZE )
-    {
-        BUILD_BUG_ON(PAGE_SIZE == STACK_SIZE);
-        unmap_domain_page(stack);
-    }
+
+    if ( stack_page )
+        unmap_domain_page(stack_page);
+
     if ( i == 0 )
         printk("Stack empty.");
     printk("\n");
@@ -296,6 +296,7 @@ static void show_guest_stack(struct vcpu *v, const struct cpu_user_regs *regs)
     int i;
     unsigned long *stack, addr;
     unsigned long mask = STACK_SIZE;
+    void *stack_page = NULL;
 
     /* Avoid HVM as we don't know what the stack looks like. */
     if ( is_hvm_vcpu(v) )
@@ -324,7 +325,7 @@ static void show_guest_stack(struct vcpu *v, const struct cpu_user_regs *regs)
         vcpu = maddr_get_owner(read_cr3()) == v->domain ? v : NULL;
         if ( !vcpu )
         {
-            stack = do_page_walk(v, (unsigned long)stack);
+            stack_page = stack = do_page_walk(v, (unsigned long)stack);
             if ( (unsigned long)stack < PAGE_SIZE )
             {
                 printk("Inaccessible guest memory.\n");
@@ -351,11 +352,10 @@ static void show_guest_stack(struct vcpu *v, const struct cpu_user_regs *regs)
         printk(" %p", _p(addr));
         stack++;
     }
-    if ( mask == PAGE_SIZE )
-    {
-        BUILD_BUG_ON(PAGE_SIZE == STACK_SIZE);
-        unmap_domain_page(stack);
-    }
+
+    if ( stack_page )
+        unmap_domain_page(stack_page);
+
     if ( i == 0 )
         printk("Stack empty.");
     printk("\n");