mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/traps: Fix handling of #DB exceptions in hypervisor context
The WARN_ON() can be triggered by guest activities, and emits a full stack trace without rate limiting. Swap it out for a ratelimited printk with just enough information to work out what is going on. Not all #DB exceptions are traps, so blindly continuing is not a safe action to take. We don't let PV guests select these settings in the real %dr7 to begin with, but for added safety against unexpected situations, detect the fault cases and crash in an obvious manner. This is part of XSA-260 / CVE-2018-8897 Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
5d37af364d
commit
75d6828bc2
1 file changed
+36
-8
+36
-8
@@ -1825,16 +1825,44 @@ void do_debug(struct cpu_user_regs *regs)
|
||||
regs->eflags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/*
|
||||
* Check for fault conditions. General Detect, and instruction
|
||||
* breakpoints are faults rather than traps, at which point attempting
|
||||
* to ignore and continue will result in a livelock.
|
||||
*/
|
||||
if ( dr6 & DR_GENERAL_DETECT )
|
||||
{
|
||||
/*
|
||||
* We ignore watchpoints when they trigger within Xen. This may
|
||||
* happen when a buffer is passed to us which previously had a
|
||||
* watchpoint set on it. No need to bump EIP; the only faulting
|
||||
* trap is an instruction breakpoint, which can't happen to us.
|
||||
*/
|
||||
WARN_ON(!search_exception_table(regs));
|
||||
printk(XENLOG_ERR "Hit General Detect in Xen context\n");
|
||||
fatal_trap(regs, 0);
|
||||
}
|
||||
|
||||
if ( dr6 & (DR_TRAP3 | DR_TRAP2 | DR_TRAP1 | DR_TRAP0) )
|
||||
{
|
||||
unsigned int bp, dr7 = read_debugreg(7) >> DR_CONTROL_SHIFT;
|
||||
|
||||
for ( bp = 0; bp < 4; ++bp )
|
||||
{
|
||||
if ( (dr6 & (1u << bp)) && /* Breakpoint triggered? */
|
||||
((dr7 & (3u << (bp * DR_CONTROL_SIZE))) == 0) /* Insn? */ )
|
||||
{
|
||||
printk(XENLOG_ERR
|
||||
"Hit instruction breakpoint in Xen context\n");
|
||||
fatal_trap(regs, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Whatever caused this #DB should be a trap. Note it and continue.
|
||||
* Guests can trigger this in certain corner cases, so ensure the
|
||||
* message is ratelimited.
|
||||
*/
|
||||
gprintk(XENLOG_WARNING,
|
||||
"Hit #DB in Xen context: %04x:%p [%ps], stk %04x:%p, dr6 %lx\n",
|
||||
regs->cs, _p(regs->rip), _p(regs->rip),
|
||||
regs->ss, _p(regs->rsp), dr6);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||