Skip to contentSkip to conversation

Patch "KVM: x86: work around infinite loop in microcode when #AC is delivered" has been added to the 4.1-stable tree

PATCH [email protected] 1 participant 1 message Dec 7, 2015

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

KVM: x86: work around infinite loop in microcode when #AC is delivered

to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
kvm-x86-work-around-infinite-loop-in-microcode-when-ac-is-delivered.patch
and it can be found in the queue-4.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 54a20552e1eae07aa240fa370a0293e006b5faed Mon Sep 17 00:00:00 2001

From: Eric Northup <[email protected]>
Date: Tue, 3 Nov 2015 18:03:53 +0100
Subject: KVM: x86: work around infinite loop in microcode when #AC is delivered

From: Eric Northup <[email protected]>

commit 54a20552e1eae07aa240fa370a0293e006b5faed upstream.

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).

---
 arch/x86/include/uapi/asm/svm.h |    1 +
 arch/x86/kvm/svm.c              |    8 ++++++++
 arch/x86/kvm/vmx.c              |    5 ++++-
 3 files changed, 13 insertions(+), 1 deletion(-)
arch/x86/include/uapi/asm/svm.h +1 -0
@@ -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" }, \
arch/x86/kvm/svm.c +8 -0
@@ -1105,6 +1105,7 @@ static void init_vmcb(struct vcpu_svm *s
 	set_exception_intercept(svm, PF_VECTOR);
 	set_exception_intercept(svm, UD_VECTOR);
 	set_exception_intercept(svm, MC_VECTOR);
+	set_exception_intercept(svm, AC_VECTOR);
 
 	set_intercept(svm, INTERCEPT_INTR);
 	set_intercept(svm, INTERCEPT_NMI);
@@ -1791,6 +1792,12 @@ static int ud_interception(struct vcpu_s
 	return 1;
 }
 
+static int ac_interception(struct vcpu_svm *svm)
+{
+	kvm_queue_exception_e(&svm->vcpu, AC_VECTOR, 0);
+	return 1;
+}
+
 static void svm_fpu_activate(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -3361,6 +3368,7 @@ static int (*const svm_exit_handlers[])(
 	[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,
arch/x86/kvm/vmx.c +4 -1
@@ -1567,7 +1567,7 @@ static void update_exception_bitmap(stru
 	u32 eb;
 
 	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) |
-	     (1u << NM_VECTOR) | (1u << DB_VECTOR);
+	     (1u << NM_VECTOR) | (1u << DB_VECTOR) | (1u << AC_VECTOR);
 	if ((vcpu->guest_debug &
 	     (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) ==
 	    (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP))
@@ -5127,6 +5127,9 @@ static int handle_exception(struct kvm_v
 		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 &

Patches currently in stable-queue which might be from [email protected] are

queue-4.1/kvm-x86-work-around-infinite-loop-in-microcode-when-ac-is-delivered.patch