diff mbox

KVM: x86: zero IDT limit on entry to SMM

Message ID 1438944883-3796-1-git-send-email-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paolo Bonzini Aug. 7, 2015, 10:54 a.m. UTC
The recent BlackHat 2015 presentation "The Memory Sinkhole"
mentions that the IDT limit is zeroed on entry to SMM.

This is not documented, and must have changed some time after 2010
(see http://www.ssi.gouv.fr/uploads/IMG/pdf/IT_Defense_2010_final.pdf).
KVM was not doing it, but the fix is easy.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/x86.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Radim Krčmář Aug. 10, 2015, 3:31 p.m. UTC | #1
2015-08-07 12:54+0200, Paolo Bonzini:
> The recent BlackHat 2015 presentation "The Memory Sinkhole"
> mentions that the IDT limit is zeroed on entry to SMM.

Slide 64 of
https://www.blackhat.com/docs/us-15/materials/us-15-Domas-The-Memory-Sinkhole-Unleashing-An-x86-Design-Flaw-Allowing-Universal-Privilege-Escalation.pdf

> This is not documented, and must have changed some time after 2010
> (see http://www.ssi.gouv.fr/uploads/IMG/pdf/IT_Defense_2010_final.pdf).
> KVM was not doing it, but the fix is easy.

This patch also clears the IDT base.  Fetching original IDT is better
done from SMM saved state (and an anti-exploit based on comparing those
two seems unlikely) so it should be fine,

Reviewed-by: Radim Kr?má? <rkrcmar@redhat.com>

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

That takes care of Attack 1.
KVM is likely not vulnerable to attack 2 and 3 because of an emergent
security feature.  (A simple modification of kvm-unit-tests show that
mapping APIC base on top of real code/data makes the APIC page hidden
and I expect SMM memslot to behave similarly.)
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5ef2560075bf..c5e88a881899 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6327,6 +6327,7 @@  static void process_smi_save_state_64(struct kvm_vcpu *vcpu, char *buf)
 static void process_smi(struct kvm_vcpu *vcpu)
 {
 	struct kvm_segment cs, ds;
+	struct desc_ptr dt;
 	char buf[512];
 	u32 cr0;
 
@@ -6359,6 +6360,10 @@  static void process_smi(struct kvm_vcpu *vcpu)
 
 	kvm_x86_ops->set_cr4(vcpu, 0);
 
+	/* Undocumented: IDT limit is set to zero on entry to SMM.  */
+	dt.address = dt.size = 0;
+	kvm_x86_ops->set_idt(vcpu, &dt);
+
 	__kvm_set_dr(vcpu, 7, DR7_FIXED_1);
 
 	cs.selector = (vcpu->arch.smbase >> 4) & 0xffff;