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@google.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
d0e536d893
commit
54a20552e1
|
@ -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" }, \
|
||||
|
|
|
@ -1019,6 +1019,7 @@ static void init_vmcb(struct vcpu_svm *svm)
|
|||
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);
|
||||
|
@ -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 void svm_fpu_activate(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_svm *svm = to_svm(vcpu);
|
||||
|
@ -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,
|
||||
|
|
|
@ -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 << 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))
|
||||
|
@ -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 &
|
||||
|
|
Loading…
Reference in New Issue