[pve-devel] [PATCH v2 kernel26] add infinite-loop-fix

Wolfgang Bumiller w.bumiller at proxmox.com
Mon Jan 25 11:43:00 CET 2016


---
 Makefile                |  1 +
 infinite-loop-fix.patch | 97 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 infinite-loop-fix.patch

diff --git a/Makefile b/Makefile
index d13e9a9..deb7656 100644
--- a/Makefile
+++ b/Makefile
@@ -207,6 +207,7 @@ ${KERNEL_SRC}/README: ${KERNEL_SRC}.org/README
 	cd ${KERNEL_SRC}; patch -p1 <../fix-idr-header-for-drbd-compilation.patch
 	cd ${KERNEL_SRC}; patch -p1 <../kvm-x86-ignore-ioapic-polarity.patch
 	cd ${KERNEL_SRC}; patch -p1 <../fix-jfs-compile-error.patch
+	cd ${KERNEL_SRC}; patch -p1 <../infinite-loop-fix.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
 	touch $@
 
diff --git a/infinite-loop-fix.patch b/infinite-loop-fix.patch
new file mode 100644
index 0000000..cdef6b8
--- /dev/null
+++ b/infinite-loop-fix.patch
@@ -0,0 +1,97 @@
+commit 54a20552e1eae07aa240fa370a0293e006b5faed
+Author: Eric Northup <digitaleric at google.com>
+Date:   Tue Nov 3 18:03:53 2015 +0100
+
+    KVM: x86: work around infinite loop in microcode when #AC is delivered
+    
+    It was found that a guest can DoS a host by triggering an infinite
+    stream of "alignment check" (#AC) exceptions.  This causes the
+    microcode to enter an infinite loop where the core never receives
+    another interrupt.  The host kernel panics pretty quickly due to the
+    effects (CVE-2015-5307).
+    
+    Signed-off-by: Eric Northup <digitaleric at google.com>
+    Cc: stable at vger.kernel.org
+    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+
+diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
+--- a/arch/x86/include/asm/kvm.h
++++ b/arch/x86/include/asm/kvm.h
+@@ -23,6 +23,7 @@
+ #define GP_VECTOR 13
+ #define PF_VECTOR 14
+ #define MF_VECTOR 16
++#define AC_VECTOR 17
+ #define MC_VECTOR 18
+ 
+ /* Select x86 specific features in <linux/kvm.h> */
+diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
+index b5d7640..8a4add8 100644
+--- a/arch/x86/include/asm/svm.h
++++ b/arch/x86/include/asm/svm.h
+@@ -100,6 +100,7 @@
+ 	{ SVM_EXIT_EXCP_BASE + UD_VECTOR,       "UD excp" }, \
+ 	{ SVM_EXIT_EXCP_BASE + PF_VECTOR,       "PF excp" }, \
+ 	{ SVM_EXIT_EXCP_BASE + NM_VECTOR,       "NM excp" }, \
++	{ SVM_EXIT_EXCP_BASE + AC_VECTOR,       "AC excp" }, \
+ 	{ SVM_EXIT_EXCP_BASE + MC_VECTOR,       "MC excp" }, \
+ 	{ SVM_EXIT_INTR,        "interrupt" }, \
+ 	{ SVM_EXIT_NMI,         "nmi" }, \
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index f2ba919..1839264 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -1019,7 +1019,8 @@ static void init_vmcb(struct vcpu_svm *svm)
+ 
+ control->intercept_exceptions = (1 << PF_VECTOR) |
+ 					(1 << UD_VECTOR) |
+-					(1 << MC_VECTOR);
++					(1 << MC_VECTOR) |
++					(1 << AC_VECTOR);
+ 
+ 	control->intercept = 	(1ULL << INTERCEPT_INTR) |
+ 				(1ULL << INTERCEPT_NMI) |
+@@ -1707,6 +1708,12 @@ static int ud_interception(struct vcpu_svm *svm)
+ 	return 1;
+ }
+ 
++static int ac_interception(struct vcpu_svm *svm)
++{
++	kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0);
++	return 1;
++}
++
+ static int nm_interception(struct vcpu_svm *svm)
+ {
+ 	svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+@@ -3270,6 +3277,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
+ 	[SVM_EXIT_EXCP_BASE + PF_VECTOR] 	= pf_interception,
+ 	[SVM_EXIT_EXCP_BASE + NM_VECTOR] 	= nm_interception,
+ 	[SVM_EXIT_EXCP_BASE + MC_VECTOR] 	= mc_interception,
++	[SVM_EXIT_EXCP_BASE + AC_VECTOR]	= ac_interception,
+ 	[SVM_EXIT_INTR] 			= intr_interception,
+ 	[SVM_EXIT_NMI]				= nmi_interception,
+ 	[SVM_EXIT_SMI]				= nop_on_interception,
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index b765b03..89aaedd 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1639,7 +1639,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
+ 	u32 eb;
+ 
+ 	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR)
+-		| (1u << NM_VECTOR);
++		| (1u << NM_VECTOR) | (1u << AC_VECTOR);
+ 	/*
+ 	 * Unconditionally intercept #DB so we can maintain dr6 without
+ 	 * reading it every exit.
+@@ -5261,6 +5261,9 @@ static int handle_exception(struct kvm_vcpu *vcpu)
+ 		return handle_rmode_exception(vcpu, ex_no, error_code);
+ 
+ 	switch (ex_no) {
++	case AC_VECTOR:
++		kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
++		return 1;
+ 	case DB_VECTOR:
+ 		dr6 = vmcs_readl(EXIT_QUALIFICATION);
+ 		if (!(vcpu->guest_debug &
-- 
2.1.4





More information about the pve-devel mailing list