diff options
author | Keir Fraser <keir@xen.org> | 2011-05-12 16:39:31 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-05-12 16:39:31 +0100 |
commit | 10fbbbcab8030eaa5771e3f69a08cd6e1e489085 (patch) | |
tree | 1344fbf5377a08105431d81bbdc387f217398c7f /xen/arch/x86/apic.c | |
parent | 3229bc7f1b7b7c0d6c771625e79493f6fab83629 (diff) | |
download | xen-10fbbbcab8030eaa5771e3f69a08cd6e1e489085.tar.gz xen-10fbbbcab8030eaa5771e3f69a08cd6e1e489085.tar.bz2 xen-10fbbbcab8030eaa5771e3f69a08cd6e1e489085.zip |
x86, vtd: [CVE-2011-1898] Protect against malicious MSIs from untrusted devices.
In the absence of VT-d interrupt remapping support, a device can send
arbitrary APIC messages to host CPUs. One class of attack that results
is to confuse the hypervisor by delivering asynchronous interrupts to
vectors that are expected to handle only synchronous
traps/exceptions.
We block this class of attack by:
(1) setting APIC.TPR=0x10, to block all interrupts below vector
0x20. This blocks delivery to all architectural exception vectors.
(2) checking APIC.ISR[vec] for vectors 0x80 (fast syscall) and 0x82
(hypercall). In these cases we BUG if we detect we are handling a
hardware interrupt -- turning a potentially more severe infiltration
into a straightforward system crash (i.e, DoS).
Thanks to Invisible Things Lab <http://www.invisiblethingslab.com>
for discovery and detailed investigation of this attack.
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r-- | xen/arch/x86/apic.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index 58f809ad42..af335607cd 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -560,12 +560,9 @@ void __devinit setup_local_APIC(void) init_apic_ldr(); /* - * Set Task Priority to 'accept all'. We never change this - * later on. + * Set Task Priority to reject any interrupts below FIRST_DYNAMIC_VECTOR. */ - value = apic_read(APIC_TASKPRI); - value &= ~APIC_TPRI_MASK; - apic_write_around(APIC_TASKPRI, value); + apic_write_around(APIC_TASKPRI, (FIRST_DYNAMIC_VECTOR & 0xF0) - 0x10); /* * After a crash, we no longer service the interrupts and a pending @@ -1439,3 +1436,9 @@ int __init APIC_init_uniprocessor (void) return 0; } + +void check_for_unexpected_msi(unsigned int vector) +{ + unsigned long v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1)); + BUG_ON(v & (1 << (vector & 0x1f))); +} |