KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798)
authorAndy Honig <ahonig@google.com>
Wed, 20 Feb 2013 22:49:16 +0000 (14:49 -0800)
committerMarcelo Tosatti <mtosatti@redhat.com>
Tue, 19 Mar 2013 17:20:21 +0000 (14:20 -0300)
If the guest specifies a IOAPIC_REG_SELECT with an invalid value and follows
that with a read of the IOAPIC_REG_WINDOW KVM does not properly validate
that request.  ioapic_read_indirect contains an
ASSERT(redir_index < IOAPIC_NUM_PINS), but the ASSERT has no effect in
non-debug builds.  In recent kernels this allows a guest to cause a kernel
oops by reading invalid memory.  In older kernels (pre-3.3) this allows a
guest to read from large ranges of host memory.

Tested: tested against apic unit tests.

Signed-off-by: Andrew Honig <ahonig@google.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
virt/kvm/ioapic.c

index ce82b94..5ba005c 100644 (file)
@@ -74,9 +74,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
                        u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
                        u64 redir_content;
 
-                       ASSERT(redir_index < IOAPIC_NUM_PINS);
+                       if (redir_index < IOAPIC_NUM_PINS)
+                               redir_content =
+                                       ioapic->redirtbl[redir_index].bits;
+                       else
+                               redir_content = ~0ULL;
 
-                       redir_content = ioapic->redirtbl[redir_index].bits;
                        result = (ioapic->ioregsel & 0x1) ?
                            (redir_content >> 32) & 0xffffffff :
                            redir_content & 0xffffffff;