aboutsummaryrefslogtreecommitdiff
path: root/system/xen/xsa/xsa201-1.patch
blob: 50983b852facaa8dd3873cc1fb0c018d1aa26033 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
From: Wei Chen <Wei.Chen@arm.com>
Subject: arm64: handle guest-generated EL1 asynchronous abort

In current code, when the hypervisor receives an asynchronous abort
from a guest, the hypervisor will do panic, the host will be down.
We have to prevent such security issue, so, in this patch we crash
the guest, when the hypervisor receives an asynchronous abort from
the guest.

This is CVE-2016-9815, part of XSA-201.

Signed-off-by: Wei Chen <Wei.Chen@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Steve Capper <steve.capper@arm.com>
Reviewed-by: Julien Grall <Julien.Grall@arm.com>

--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -204,9 +204,12 @@ guest_fiq_invalid:
         entry   hyp=0, compat=0
         invalid BAD_FIQ

-guest_error_invalid:
+guest_error:
         entry   hyp=0, compat=0
-        invalid BAD_ERROR
+        msr     daifclr, #2
+        mov     x0, sp
+        bl      do_trap_guest_error
+        exit    hyp=0, compat=0

 guest_sync_compat:
         entry   hyp=0, compat=1
@@ -225,9 +228,12 @@ guest_fiq_invalid_compat:
         entry   hyp=0, compat=1
         invalid BAD_FIQ

-guest_error_invalid_compat:
+guest_error_compat:
         entry   hyp=0, compat=1
-        invalid BAD_ERROR
+        msr     daifclr, #2
+        mov     x0, sp
+        bl      do_trap_guest_error
+        exit    hyp=0, compat=1

 ENTRY(return_to_new_vcpu32)
         exit    hyp=0, compat=1
@@ -286,12 +292,12 @@ ENTRY(hyp_traps_vector)
         ventry  guest_sync                      // Synchronous 64-bit EL0/EL1
         ventry  guest_irq                       // IRQ 64-bit EL0/EL1
         ventry  guest_fiq_invalid               // FIQ 64-bit EL0/EL1
-        ventry  guest_error_invalid             // Error 64-bit EL0/EL1
+        ventry  guest_error                     // Error 64-bit EL0/EL1

         ventry  guest_sync_compat               // Synchronous 32-bit EL0/EL1
         ventry  guest_irq_compat                // IRQ 32-bit EL0/EL1
         ventry  guest_fiq_invalid_compat        // FIQ 32-bit EL0/EL1
-        ventry  guest_error_invalid_compat      // Error 32-bit EL0/EL1
+        ventry  guest_error_compat              // Error 32-bit EL0/EL1

 /*
  * struct vcpu *__context_switch(struct vcpu *prev, struct vcpu *next)
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -2723,6 +2723,21 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs)
     }
 }

+asmlinkage void do_trap_guest_error(struct cpu_user_regs *regs)
+{
+    enter_hypervisor_head(regs);
+
+    /*
+     * Currently, to ensure hypervisor safety, when we received a
+     * guest-generated vSerror/vAbort, we just crash the guest to protect
+     * the hypervisor. In future we can better handle this by injecting
+     * a vSerror/vAbort to the guest.
+     */
+    gdprintk(XENLOG_WARNING, "Guest(Dom-%u) will be crashed by vSError\n",
+             current->domain->domain_id);
+    domain_crash_synchronous();
+}
+
 asmlinkage void do_trap_irq(struct cpu_user_regs *regs)
 {
     enter_hypervisor_head(regs);