[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen/arm: Don't let guess access to Debug and Performance Monitor registers
commit 0b182202fef8ebfc093a00ead9414a683eb8807c Author: Julien Grall <julien.grall@xxxxxxxxxx> AuthorDate: Tue Apr 15 14:06:42 2014 +0100 Commit: Ian Campbell <ian.campbell@xxxxxxxxxx> CommitDate: Wed Apr 23 10:31:07 2014 +0100 xen/arm: Don't let guess access to Debug and Performance Monitor registers Debug and performance registers are not properly switched by Xen. Trap them and inject an undefined instruction, except for those registers which might be unconditionally accessed which we implement as RAZ/WI. This is CVE-2014-2915 / XSA-93. Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- xen/arch/arm/traps.c | 59 +++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/cpregs.h | 2 + xen/include/asm-arm/processor.h | 11 ++++++- xen/include/asm-arm/sysregs.h | 43 ++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 710e5cc..822848f 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -74,6 +74,10 @@ void __cpuinit init_traps(void) /* Setup Hyp vector base */ WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2); + /* Trap Debug and Performance Monitor accesses */ + WRITE_SYSREG(HDCR_TDRA|HDCR_TDOSA|HDCR_TDA|HDCR_TPM|HDCR_TPMCR, + MDCR_EL2); + /* Trap CP15 c15 used for implementation defined registers */ WRITE_SYSREG(HSTR_T(15), HSTR_EL2); @@ -1412,6 +1416,17 @@ static void do_cp15_64(struct cpu_user_regs *regs, advance_pc(regs, hsr); } +static void do_cp14(struct cpu_user_regs *regs, union hsr hsr) +{ + if ( !check_conditional_instr(regs, hsr) ) + { + advance_pc(regs, hsr); + return; + } + + inject_undef32_exception(regs); +} + static void do_cp(struct cpu_user_regs *regs, union hsr hsr) { if ( !check_conditional_instr(regs, hsr) ) @@ -1427,9 +1442,46 @@ static void do_cp(struct cpu_user_regs *regs, union hsr hsr) static void do_sysreg(struct cpu_user_regs *regs, union hsr hsr) { + register_t *x = select_user_reg(regs, hsr.sysreg.reg); switch ( hsr.bits & HSR_SYSREG_REGS_MASK ) { + /* RAZ/WI registers: */ + /* - Debug */ + case HSR_SYSREG_MDSCR_EL1: + /* - Perf monitors */ + case HSR_SYSREG_PMINTENSET_EL1: + case HSR_SYSREG_PMINTENCLR_EL1: + case HSR_SYSREG_PMCR_EL0: + case HSR_SYSREG_PMCNTENSET_EL0: + case HSR_SYSREG_PMCNTENCLR_EL0: + case HSR_SYSREG_PMOVSCLR_EL0: + case HSR_SYSREG_PMSWINC_EL0: + case HSR_SYSREG_PMSELR_EL0: + case HSR_SYSREG_PMCEID0_EL0: + case HSR_SYSREG_PMCEID1_EL0: + case HSR_SYSREG_PMCCNTR_EL0: + case HSR_SYSREG_PMXEVTYPER_EL0: + case HSR_SYSREG_PMXEVCNTR_EL0: + case HSR_SYSREG_PMUSERENR_EL0: + case HSR_SYSREG_PMOVSSET_EL0: + /* - Breakpoints */ + HSR_SYSREG_DBG_CASES(DBGBVR): + HSR_SYSREG_DBG_CASES(DBGBCR): + /* - Watchpoints */ + HSR_SYSREG_DBG_CASES(DBGWVR): + HSR_SYSREG_DBG_CASES(DBGWCR): + if ( hsr.sysreg.read ) + *x = 0; + /* else: write ignored */ + break; + + /* Write only, Write ignore registers: */ + case HSR_SYSREG_OSLAR_EL1: + if ( hsr.sysreg.read ) + goto bad_sysreg; + /* else: write ignored */ + break; case HSR_SYSREG_CNTP_CTL_EL0: case HSR_SYSREG_CNTP_TVAL_EL0: if ( !vtimer_emulate(regs, hsr) ) @@ -1440,6 +1492,7 @@ static void do_sysreg(struct cpu_user_regs *regs, } break; default: + bad_sysreg: { struct hsr_sysreg sysreg = hsr.sysreg; #ifndef NDEBUG @@ -1614,6 +1667,12 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs *regs) goto bad_trap; do_cp15_64(regs, hsr); break; + case HSR_EC_CP14_32: + case HSR_EC_CP14_DBG: + if ( !is_32bit_domain(current->domain) ) + goto bad_trap; + do_cp14(regs, hsr); + break; case HSR_EC_CP: if ( !is_32bit_domain(current->domain) ) goto bad_trap; diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h index e9a8094..bf8133e 100644 --- a/xen/include/asm-arm/cpregs.h +++ b/xen/include/asm-arm/cpregs.h @@ -115,6 +115,7 @@ #define NSACR p15,0,c1,c1,2 /* Non-Secure Access Control Register */ #define HSCTLR p15,4,c1,c0,0 /* Hyp. System Control Register */ #define HCR p15,4,c1,c1,0 /* Hyp. Configuration Register */ +#define HDCR p15,4,c1,c1,1 /* Hyp. Debug Configuration Register */ #define HCPTR p15,4,c1,c1,2 /* Hyp. Coprocessor Trap Register */ #define HSTR p15,4,c1,c1,3 /* Hyp. System Trap Register */ @@ -287,6 +288,7 @@ #define ID_PFR0_EL1 ID_PFR0 #define ID_PFR1_EL1 ID_PFR1 #define IFSR32_EL2 IFSR +#define MDCR_EL2 HDCR #define MIDR_EL1 MIDR #define MPIDR_EL1 MPIDR #define PAR_EL1 PAR diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h index 750864a..9267c1b 100644 --- a/xen/include/asm-arm/processor.h +++ b/xen/include/asm-arm/processor.h @@ -92,12 +92,19 @@ /* HSTR Hyp. System Trap Register */ #define HSTR_T(x) ((_AC(1,U)<<(x))) /* Trap Cp15 c<x> */ +/* HDCR Hyp. Debug Configuration Register */ +#define HDCR_TDRA (_AC(1,U)<<11) /* Trap Debug ROM access */ +#define HDCR_TDOSA (_AC(1,U)<<10) /* Trap Debug-OS-related register access */ +#define HDCR_TDA (_AC(1,U)<<9) /* Trap Debug Access */ +#define HDCR_TPM (_AC(1,U)<<6) /* Trap Performance Monitors accesses */ +#define HDCR_TPMCR (_AC(1,U)<<5) /* Trap PMCR accesses */ + #define HSR_EC_UNKNOWN 0x00 #define HSR_EC_WFI_WFE 0x01 #define HSR_EC_CP15_32 0x03 #define HSR_EC_CP15_64 0x04 -#define HSR_EC_CP14_32 0x05 -#define HSR_EC_CP14_DBG 0x06 +#define HSR_EC_CP14_32 0x05 /* Trapped MCR or MRC access to CP14 */ +#define HSR_EC_CP14_DBG 0x06 /* Trapped LDC/STC access to CP14 (only for debug registers) */ #define HSR_EC_CP 0x07 /* HCPTR-trapped access to CP0-CP13 */ #define HSR_EC_CP10 0x08 #define HSR_EC_JAZELLE 0x09 diff --git a/xen/include/asm-arm/sysregs.h b/xen/include/asm-arm/sysregs.h index 0cee0e9..4a4de34 100644 --- a/xen/include/asm-arm/sysregs.h +++ b/xen/include/asm-arm/sysregs.h @@ -40,6 +40,31 @@ ((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \ ((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT) +#define HSR_SYSREG_MDSCR_EL1 HSR_SYSREG(2,0,c0,c2,2) +#define HSR_SYSREG_OSLAR_EL1 HSR_SYSREG(2,0,c1,c0,4) + +#define HSR_SYSREG_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4) +#define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5) +#define HSR_SYSREG_DBGWVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,6) +#define HSR_SYSREG_DBGWCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,7) + +#define HSR_SYSREG_DBG_CASES(REG) case HSR_SYSREG_##REG##n_EL1(0): \ + case HSR_SYSREG_##REG##n_EL1(1): \ + case HSR_SYSREG_##REG##n_EL1(2): \ + case HSR_SYSREG_##REG##n_EL1(3): \ + case HSR_SYSREG_##REG##n_EL1(4): \ + case HSR_SYSREG_##REG##n_EL1(5): \ + case HSR_SYSREG_##REG##n_EL1(6): \ + case HSR_SYSREG_##REG##n_EL1(7): \ + case HSR_SYSREG_##REG##n_EL1(8): \ + case HSR_SYSREG_##REG##n_EL1(9): \ + case HSR_SYSREG_##REG##n_EL1(10): \ + case HSR_SYSREG_##REG##n_EL1(11): \ + case HSR_SYSREG_##REG##n_EL1(12): \ + case HSR_SYSREG_##REG##n_EL1(13): \ + case HSR_SYSREG_##REG##n_EL1(14): \ + case HSR_SYSREG_##REG##n_EL1(15) + #define HSR_SYSREG_SCTLR_EL1 HSR_SYSREG(3,0,c1, c0,0) #define HSR_SYSREG_TTBR0_EL1 HSR_SYSREG(3,0,c2, c0,0) #define HSR_SYSREG_TTBR1_EL1 HSR_SYSREG(3,0,c2, c0,1) @@ -48,10 +73,28 @@ #define HSR_SYSREG_AFSR1_EL1 HSR_SYSREG(3,0,c5, c1,1) #define HSR_SYSREG_ESR_EL1 HSR_SYSREG(3,0,c5, c2,0) #define HSR_SYSREG_FAR_EL1 HSR_SYSREG(3,0,c6, c0,0) +#define HSR_SYSREG_PMINTENSET_EL1 HSR_SYSREG(3,0,c9,c14,1) +#define HSR_SYSREG_PMINTENCLR_EL1 HSR_SYSREG(3,0,c9,c14,2) #define HSR_SYSREG_MAIR_EL1 HSR_SYSREG(3,0,c10,c2,0) #define HSR_SYSREG_AMAIR_EL1 HSR_SYSREG(3,0,c10,c3,0) #define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1) +#define HSR_SYSREG_PMCR_EL0 HSR_SYSREG(3,3,c9,c12,0) +#define HSR_SYSREG_PMCNTENSET_EL0 HSR_SYSREG(3,3,c9,c12,1) +#define HSR_SYSREG_PMCNTENCLR_EL0 HSR_SYSREG(3,3,c9,c12,2) +#define HSR_SYSREG_PMOVSCLR_EL0 HSR_SYSREG(3,3,c9,c12,3) +#define HSR_SYSREG_PMSWINC_EL0 HSR_SYSREG(3,3,c9,c12,4) +#define HSR_SYSREG_PMSELR_EL0 HSR_SYSREG(3,3,c9,c12,5) +#define HSR_SYSREG_PMCEID0_EL0 HSR_SYSREG(3,3,c9,c12,6) +#define HSR_SYSREG_PMCEID1_EL0 HSR_SYSREG(3,3,c9,c12,7) + +#define HSR_SYSREG_PMCCNTR_EL0 HSR_SYSREG(3,3,c9,c13,0) +#define HSR_SYSREG_PMXEVTYPER_EL0 HSR_SYSREG(3,3,c9,c13,1) +#define HSR_SYSREG_PMXEVCNTR_EL0 HSR_SYSREG(3,3,c9,c13,2) + +#define HSR_SYSREG_PMUSERENR_EL0 HSR_SYSREG(3,3,c9,c14,0) +#define HSR_SYSREG_PMOVSSET_EL0 HSR_SYSREG(3,3,c9,c14,3) + #define HSR_SYSREG_CNTPCT_EL0 HSR_SYSREG(3,3,c14,c0,0) #define HSR_SYSREG_CNTP_CTL_EL0 HSR_SYSREG(3,3,c14,c2,1) #define HSR_SYSREG_CNTP_TVAL_EL0 HSR_SYSREG(3,3,c14,c2,0) -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |