Patchwork KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798)

login
register
mail settings
Submitter Luis Henriques
Date May 20, 2013, 12:06 p.m.
Message ID <1369051596-12689-1-git-send-email-luis.henriques@canonical.com>
Download mbox | patch
Permalink /patch/245012/
State New
Headers show

Comments

Luis Henriques - May 20, 2013, 12:06 p.m.
From: Andy Honig <ahonig@google.com>

CVE-2013-1798

BugLink: https://bugs.launchpad.net/bugs/1158262

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>
(cherry picked from commit a2c118bfab8bc6b8bb213abfc35201e441693d55)

Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 virt/kvm/ioapic.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
Luis Henriques - May 20, 2013, 12:09 p.m.
On Mon, May 20, 2013 at 01:06:36PM +0100, Luis Henriques wrote:
> From: Andy Honig <ahonig@google.com>
> 
> CVE-2013-1798
> 
> BugLink: https://bugs.launchpad.net/bugs/1158262
> 
> 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>
> (cherry picked from commit a2c118bfab8bc6b8bb213abfc35201e441693d55)
> 
> Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
> ---
>  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 9fe140b..69969ae 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -71,9 +71,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;
> -- 
> 1.8.1.2
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team

Cheers,
--
Luis
Andy Whitcroft - May 20, 2013, 2:57 p.m.
On Mon, May 20, 2013 at 01:06:36PM +0100, Luis Henriques wrote:
> From: Andy Honig <ahonig@google.com>
> 
> CVE-2013-1798
> 
> BugLink: https://bugs.launchpad.net/bugs/1158262
> 
> 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>
> (cherry picked from commit a2c118bfab8bc6b8bb213abfc35201e441693d55)
> 
> Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
> ---
>  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 9fe140b..69969ae 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -71,9 +71,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;
> -- 

Simple upstream cherrypick of the above sha1.  Looks to return -1 for
invalid reads.

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw

Patch

diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 9fe140b..69969ae 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -71,9 +71,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;