40 lines
1.4 KiB
Diff
40 lines
1.4 KiB
Diff
From: Andy Honig <ahonig@google.com>
|
|
Date: Mon, 11 Mar 2013 09:34:52 -0700
|
|
Subject: KVM: x86: fix for buffer overflow in handling of MSR_KVM_SYSTEM_TIME
|
|
(CVE-2013-1796)
|
|
|
|
commit c300aa64ddf57d9c5d9c898a64b36877345dd4a9 upstream.
|
|
|
|
If the guest sets the GPA of the time_page so that the request to update the
|
|
time straddles a page then KVM will write onto an incorrect page. The
|
|
write is done byusing kmap atomic to get a pointer to the page for the time
|
|
structure and then performing a memcpy to that page starting at an offset
|
|
that the guest controls. Well behaved guests always provide a 32-byte aligned
|
|
address, however a malicious guest could use this to corrupt host kernel
|
|
memory.
|
|
|
|
Tested: Tested against kvmclock unit test.
|
|
|
|
Signed-off-by: Andrew Honig <ahonig@google.com>
|
|
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
|
---
|
|
arch/x86/kvm/x86.c | 5 +++++
|
|
1 file changed, 5 insertions(+)
|
|
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
|
index f7c850b..2ade60c 100644
|
|
--- a/arch/x86/kvm/x86.c
|
|
+++ b/arch/x86/kvm/x86.c
|
|
@@ -1959,6 +1959,11 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
|
/* ...but clean it before doing the actual write */
|
|
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
|
|
|
|
+ /* Check that the address is 32-byte aligned. */
|
|
+ if (vcpu->arch.time_offset &
|
|
+ (sizeof(struct pvclock_vcpu_time_info) - 1))
|
|
+ break;
|
|
+
|
|
vcpu->arch.time_page =
|
|
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
|
|
|