xen/arm: Inject an undefined instruction when the coproc/sysreg is not handled

Currently Xen panics if it's unable to handle a coprocessor/sysreg instruction.
Replace this behavior by inject an undefined instruction to the faulty guest
and log if Xen is in debug mode.

This is CVE-2014-2915 / XSA-93.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Julien Grall authored and Ian Campbell committed 2014-04-23 10:30:33 +01:00
1 parent 8cfc8e5206
commit 60f737636c
1 file changed
+41 -20
+41 -20
View File
@@ -1351,10 +1351,16 @@ static void do_cp15_32(struct cpu_user_regs *regs,
*r = v->arch.actlr;
break;
default:
printk("%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
cp32.read ? "mrc" : "mcr",
cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
panic("unhandled 32-bit CP15 access %#x", hsr.bits & HSR_CP32_REGS_MASK);
#ifndef NDEBUG
gdprintk(XENLOG_ERR,
"%s p15, %d, r%d, cr%d, cr%d, %d @ 0x%"PRIregister"\n",
cp32.read ? "mrc" : "mcr",
cp32.op1, cp32.reg, cp32.crn, cp32.crm, cp32.op2, regs->pc);
gdprintk(XENLOG_ERR, "unhandled 32-bit CP15 access %#x",
hsr.bits & HSR_CP32_REGS_MASK);
#endif
inject_undef32_exception(regs);
return;
}
advance_pc(regs, hsr);
}
@@ -1362,8 +1368,6 @@ static void do_cp15_32(struct cpu_user_regs *regs,
static void do_cp15_64(struct cpu_user_regs *regs,
union hsr hsr)
{
struct hsr_cp64 cp64 = hsr.cp64;
if ( !check_conditional_instr(regs, hsr) )
{
advance_pc(regs, hsr);
@@ -1381,10 +1385,20 @@ static void do_cp15_64(struct cpu_user_regs *regs,
}
break;
default:
printk("%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
cp64.read ? "mrrc" : "mcrr",
cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
panic("unhandled 64-bit CP15 access %#x", hsr.bits & HSR_CP64_REGS_MASK);
{
#ifndef NDEBUG
struct hsr_cp64 cp64 = hsr.cp64;
gdprintk(XENLOG_ERR,
"%s p15, %d, r%d, r%d, cr%d @ 0x%"PRIregister"\n",
cp64.read ? "mrrc" : "mcrr",
cp64.op1, cp64.reg1, cp64.reg2, cp64.crm, regs->pc);
gdprintk(XENLOG_ERR, "unhandled 64-bit CP15 access %#x",
hsr.bits & HSR_CP64_REGS_MASK);
#endif
inject_undef32_exception(regs);
return;
}
}
advance_pc(regs, hsr);
}
@@ -1393,7 +1407,6 @@ static void do_cp15_64(struct cpu_user_regs *regs,
static void do_sysreg(struct cpu_user_regs *regs,
union hsr hsr)
{
struct hsr_sysreg sysreg = hsr.sysreg;
switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
{
@@ -1407,15 +1420,23 @@ static void do_sysreg(struct cpu_user_regs *regs,
}
break;
default:
printk("%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
sysreg.read ? "mrs" : "msr",
sysreg.op0, sysreg.op1,
sysreg.crn, sysreg.crm,
sysreg.op2,
sysreg.read ? "=>" : "<=",
sysreg.reg, regs->pc);
panic("unhandled 64-bit sysreg access %#x",
hsr.bits & HSR_SYSREG_REGS_MASK);
{
struct hsr_sysreg sysreg = hsr.sysreg;
#ifndef NDEBUG
gdprintk(XENLOG_ERR,
"%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
sysreg.read ? "mrs" : "msr",
sysreg.op0, sysreg.op1,
sysreg.crn, sysreg.crm,
sysreg.op2,
sysreg.read ? "=>" : "<=",
sysreg.reg, regs->pc);
gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x",
hsr.bits & HSR_SYSREG_REGS_MASK);
#endif
inject_undef64_exception(regs, sysreg.len);
}
}
regs->pc += 4;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.