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

[Xen-devel] [PATCH 12/12] xen: arm: Dump guest state when invalid trap state is detected



By adding GUEST_BUG_ON locally to traps.c.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
v3: New patch
---
 xen/arch/arm/traps.c |   58 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 8fec036..b4f654a 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -63,6 +63,30 @@ static inline void check_stack_alignment_constraints(void) {
 #endif
 }
 
+/*
+ * GUEST_BUG_ON is intended for checking that the guest state has not been
+ * corrupted in hardware and/or that the hardware behaves as we
+ * believe it should (i.e. that certain traps can only occur when the
+ * guest is in a particular mode).
+ *
+ * The intention is to limit the damage such h/w bugs (or spec
+ * misunderstandings) can do by turning them into Denial of Service
+ * attacks instead of e.g. information leaks or privilege escalations.
+ *
+ * GUEST_BUG_ON *MUST* *NOT* be used to check for guest controllable state!
+ *
+ * Compared with regular BUG_ON it dumps the guest vcpu state instead
+ * of Xen's state.
+ */
+#define guest_bug_on_failed(p)                          \
+do {                                                    \
+    show_execution_state(guest_cpu_user_regs());        \
+    panic("Guest Bug: %pv: '%s', line %d, file %s\n",   \
+          current, p, __LINE__, __FILE__);              \
+} while (0)
+#define GUEST_BUG_ON(p) \
+    do { if ( unlikely(p) ) guest_bug_on_failed(#p); } while (0)
+
 #ifdef CONFIG_ARM_32
 static int debug_stack_lines = 20;
 #define stack_words_per_line 8
@@ -1565,7 +1589,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
     switch ( hsr.bits & HSR_CP32_REGS_MASK )
     {
     case HSR_CPREG32(CLIDR):
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         if ( !cp32.read )
         {
             dprintk(XENLOG_ERR,
@@ -1575,7 +1599,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
         *r = READ_SYSREG32(CLIDR_EL1);
         break;
     case HSR_CPREG32(CCSIDR):
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         if ( !cp32.read )
         {
             dprintk(XENLOG_ERR,
@@ -1585,7 +1609,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
         *r = READ_SYSREG32(CCSIDR_EL1);
         break;
     case HSR_CPREG32(DCCISW):
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         if ( cp32.read )
         {
             dprintk(XENLOG_ERR,
@@ -1604,7 +1628,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
             goto undef_cp15_32;
         break;
     case HSR_CPREG32(ACTLR):
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         if ( cp32.read )
            *r = v->arch.actlr;
         break;
@@ -1626,7 +1650,7 @@ static void do_cp15_32(struct cpu_user_regs *regs,
     case HSR_CPREG32(PMINTENSET):
     case HSR_CPREG32(PMINTENCLR):
         /* EL1 only */
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         goto cp15_32_raz_wi;
 
     case HSR_CPREG32(PMCR):
@@ -1867,7 +1891,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
     /* - Double Lock Register */
     case HSR_SYSREG_OSDLR_EL1:
         /* EL1 only */
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         goto sysreg_raz_wi;
 
     case HSR_SYSREG_PMUSERENR_EL0:
@@ -1914,7 +1938,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
 
     /* Write only, Write ignore registers: */
     case HSR_SYSREG_OSLAR_EL1:
-        BUG_ON(psr_mode_is_user(regs));
+        GUEST_BUG_ON(psr_mode_is_user(regs));
         if ( hsr.sysreg.read )
             goto undef_sysreg;
         /* else: write ignored */
@@ -2114,37 +2138,37 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs 
*regs)
         advance_pc(regs, hsr);
         break;
     case HSR_EC_CP15_32:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_cp15_32);
         do_cp15_32(regs, hsr);
         break;
     case HSR_EC_CP15_64:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_cp15_64);
         do_cp15_64(regs, hsr);
         break;
     case HSR_EC_CP14_32:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_cp14_32);
         do_cp14_32(regs, hsr);
         break;
     case HSR_EC_CP14_DBG:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_cp14_dbg);
         do_cp14_dbg(regs, hsr);
         break;
     case HSR_EC_CP:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_cp);
         do_cp(regs, hsr);
         break;
     case HSR_EC_SMC32:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_smc32);
         inject_undef_exception(regs, hsr.len);
         break;
     case HSR_EC_HVC32:
-        BUG_ON(!psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr));
 #ifndef NDEBUG
         if ( (hsr.iss & 0xff00) == 0xff00 )
             return do_debug_trap(regs, hsr.iss & 0x00ff);
@@ -2155,7 +2179,7 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs 
*regs)
         break;
 #ifdef CONFIG_ARM_64
     case HSR_EC_HVC64:
-        BUG_ON(psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_hvc64);
 #ifndef NDEBUG
         if ( (hsr.iss & 0xff00) == 0xff00 )
@@ -2166,12 +2190,12 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs 
*regs)
         do_trap_hypercall(regs, &regs->x16, hsr.iss);
         break;
     case HSR_EC_SMC64:
-        BUG_ON(psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_smc64);
         inject_undef64_exception(regs, hsr.len);
         break;
     case HSR_EC_SYSREG:
-        BUG_ON(psr_mode_is_32bit(regs->cpsr));
+        GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr));
         perfc_incr(trap_sysreg);
         do_sysreg(regs, hsr);
         break;
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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