aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64/entry.S
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-05-12 16:39:31 +0100
committerKeir Fraser <keir@xen.org>2011-05-12 16:39:31 +0100
commit10fbbbcab8030eaa5771e3f69a08cd6e1e489085 (patch)
tree1344fbf5377a08105431d81bbdc387f217398c7f /xen/arch/x86/x86_64/entry.S
parent3229bc7f1b7b7c0d6c771625e79493f6fab83629 (diff)
downloadxen-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/x86_64/entry.S')
-rw-r--r--xen/arch/x86/x86_64/entry.S8
1 files changed, 8 insertions, 0 deletions
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 6cf35f338e..4d49c4331c 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -297,6 +297,14 @@ ENTRY(int80_direct_trap)
pushq $0
SAVE_ALL
+ cmpb $0,untrusted_msi(%rip)
+UNLIKELY_START(ne, msi_check)
+ movl $0x80,%edi
+ call check_for_unexpected_msi
+ RESTORE_ALL
+ SAVE_ALL
+UNLIKELY_END(msi_check)
+
GET_CURRENT(%rbx)
/* Check that the callback is non-null. */