Patchwork [3.5.y.z,extended,stable] Patch "KVM: Fix bounds checking in ioapic indirect register reads" has been added to staging queue

mail settings
Submitter Luis Henriques
Date April 11, 2013, 9:09 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/235640/
State New
Headers show


Luis Henriques - April 11, 2013, 9:09 a.m.
This is a note to let you know that I have just added a patch titled

    KVM: Fix bounds checking in ioapic indirect register reads

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 7d2891cde449076d4425e94c0c6a9ad6e9acd9b6 Mon Sep 17 00:00:00 2001
From: Andy Honig <>
Date: Wed, 20 Feb 2013 14:49:16 -0800
Subject: [PATCH] KVM: Fix bounds checking in ioapic indirect register reads

commit a2c118bfab8bc6b8bb213abfc35201e441693d55 upstream.

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 <>
Signed-off-by: Marcelo Tosatti <>
Signed-off-by: Luis Henriques <>
 virt/kvm/ioapic.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)



diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 26fd54d..fdb1faf 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -73,9 +73,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;