[kernel] r18974 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/x86 patches/series

Dann Frazier dannf at alioth.debian.org
Fri May 4 03:40:15 UTC 2012


Author: dannf
Date: Fri May  4 03:40:13 2012
New Revision: 18974

Log:
KVM: Ensure all vcpus are consistent with in-kernel irqchip settings
(CVE-2012-1601)

Added:
   dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-irqchip-settings.patch
   dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-disallow-multiple-KVM_CREATE_IRQCHIP.patch
Modified:
   dists/squeeze-security/linux-2.6/debian/changelog
   dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze3

Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog	Wed May  2 04:17:01 2012	(r18973)
+++ dists/squeeze-security/linux-2.6/debian/changelog	Fri May  4 03:40:13 2012	(r18974)
@@ -3,6 +3,8 @@
   * CVE-2012-0879:
     - block: Fix io_context leak after clone with CLONE_IO
     - block: Fix io_context leak after failure of clone with CLONE_IO
+  * KVM: Ensure all vcpus are consistent with in-kernel irqchip settings
+    (CVE-2012-1601)
 
  -- dann frazier <dannf at debian.org>  Thu, 26 Apr 2012 23:29:43 -0600
 

Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-irqchip-settings.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-irqchip-settings.patch	Fri May  4 03:40:13 2012	(r18974)
@@ -0,0 +1,97 @@
+commit 3e515705a1f46beb1c942bb8043c16f8ac7b1e9e
+Author: Avi Kivity <avi at redhat.com>
+Date:   Mon Mar 5 14:23:29 2012 +0200
+
+    KVM: Ensure all vcpus are consistent with in-kernel irqchip settings
+    
+    If some vcpus are created before KVM_CREATE_IRQCHIP, then
+    irqchip_in_kernel() and vcpu->arch.apic will be inconsistent, leading
+    to potential NULL pointer dereferences.
+    
+    Fix by:
+    - ensuring that no vcpus are installed when KVM_CREATE_IRQCHIP is called
+    - ensuring that a vcpu has an apic if it is installed after KVM_CREATE_IRQCHIP
+    
+    This is somewhat long winded because vcpu->arch.apic is created without
+    kvm->lock held.
+    
+    Based on earlier patch by Michael Ellerman.
+    
+    Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
+    Signed-off-by: Avi Kivity <avi at redhat.com>
+    [dannf: backported to Debian's 2.6.32]
+
+diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
+index 2eb6365..416122b 100644
+--- a/arch/ia64/kvm/kvm-ia64.c
++++ b/arch/ia64/kvm/kvm-ia64.c
+@@ -1185,6 +1185,11 @@ out:
+ 
+ #define PALE_RESET_ENTRY    0x80000000ffffffb0UL
+ 
++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
++{
++	return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL);
++}
++
+ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+ {
+ 	struct kvm_vcpu *v;
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 39a11bd..2ebf763 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -2396,6 +2396,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
+ 		r = -EEXIST;
+ 		if (kvm->arch.vpic)
+ 			goto create_irqchip_unlock;
++		r = -EINVAL;
++		if (atomic_read(&kvm->online_vcpus))
++			goto create_irqchip_unlock;
+ 		r = -ENOMEM;
+ 		vpic = kvm_create_pic(kvm);
+ 		if (vpic) {
+@@ -5154,6 +5157,11 @@ void kvm_arch_check_processor_compat(void *rtn)
+ 	kvm_x86_ops->check_processor_compatibility(rtn);
+ }
+ 
++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu)
++{
++	return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL);
++}
++
+ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
+ {
+ 	struct page *page;
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index c728a50..8bfed57 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -556,5 +556,12 @@ static inline bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
+ {
+ 	return vcpu->kvm->bsp_vcpu_id == vcpu->vcpu_id;
+ }
++
++bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu);
++
++#else
++
++static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; }
++
+ #endif
+ #endif
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 311ec18..82b6fdc 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -1857,6 +1857,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
+ 		return r;
+ 
+ 	mutex_lock(&kvm->lock);
++	if (!kvm_vcpu_compatible(vcpu)) {
++		r = -EINVAL;
++		goto vcpu_destroy;
++	}
+ 	if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) {
+ 		r = -EINVAL;
+ 		goto vcpu_destroy;

Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-disallow-multiple-KVM_CREATE_IRQCHIP.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/x86/KVM-disallow-multiple-KVM_CREATE_IRQCHIP.patch	Fri May  4 03:40:13 2012	(r18974)
@@ -0,0 +1,81 @@
+commit 3ddea128ad75bd33e88780fe44f44c3717369b98
+Author: Marcelo Tosatti <mtosatti at redhat.com>
+Date:   Thu Oct 29 13:44:15 2009 -0200
+
+    KVM: x86: disallow multiple KVM_CREATE_IRQCHIP
+    
+    Otherwise kvm will leak memory on multiple KVM_CREATE_IRQCHIP.
+    Also serialize multiple accesses with kvm->lock.
+    
+    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+    Signed-off-by: Avi Kivity <avi at redhat.com>
+
+diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
+index c025a23..be399e2 100644
+--- a/arch/x86/kvm/irq.h
++++ b/arch/x86/kvm/irq.h
+@@ -86,7 +86,11 @@ static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
+ 
+ static inline int irqchip_in_kernel(struct kvm *kvm)
+ {
+-	return pic_irqchip(kvm) != NULL;
++	int ret;
++
++	ret = (pic_irqchip(kvm) != NULL);
++	smp_rmb();
++	return ret;
+ }
+ 
+ void kvm_pic_reset(struct kvm_kpic_state *s);
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 719f31e..97f6f95 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -2362,25 +2362,39 @@ long kvm_arch_vm_ioctl(struct file *filp,
+ 		if (r)
+ 			goto out;
+ 		break;
+-	case KVM_CREATE_IRQCHIP:
++	case KVM_CREATE_IRQCHIP: {
++		struct kvm_pic *vpic;
++
++		mutex_lock(&kvm->lock);
++		r = -EEXIST;
++		if (kvm->arch.vpic)
++			goto create_irqchip_unlock;
+ 		r = -ENOMEM;
+-		kvm->arch.vpic = kvm_create_pic(kvm);
+-		if (kvm->arch.vpic) {
++		vpic = kvm_create_pic(kvm);
++		if (vpic) {
+ 			r = kvm_ioapic_init(kvm);
+ 			if (r) {
+-				kfree(kvm->arch.vpic);
+-				kvm->arch.vpic = NULL;
+-				goto out;
++				kfree(vpic);
++				goto create_irqchip_unlock;
+ 			}
+ 		} else
+-			goto out;
++			goto create_irqchip_unlock;
++		smp_wmb();
++		kvm->arch.vpic = vpic;
++		smp_wmb();
+ 		r = kvm_setup_default_irq_routing(kvm);
+ 		if (r) {
++			mutex_lock(&kvm->irq_lock);
+ 			kfree(kvm->arch.vpic);
+ 			kfree(kvm->arch.vioapic);
+-			goto out;
++			kvm->arch.vpic = NULL;
++			kvm->arch.vioapic = NULL;
++			mutex_unlock(&kvm->irq_lock);
+ 		}
++	create_irqchip_unlock:
++		mutex_unlock(&kvm->lock);
+ 		break;
++	}
+ 	case KVM_CREATE_PIT:
+ 		u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
+ 		goto create_pit;

Modified: dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze3
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze3	Wed May  2 04:17:01 2012	(r18973)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze3	Fri May  4 03:40:13 2012	(r18974)
@@ -1,2 +1,4 @@
 + bugfix/all/block-Fix-io_context-leak-after-clone-with-CLONE_IO.patch
 + bugfix/all/block-Fix-io_context-leak-after-failure-of-clone-with-CLONE_IO.patch
++ bugfix/x86/KVM-disallow-multiple-KVM_CREATE_IRQCHIP.patch
++ bugfix/x86/KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-irqchip-settings.patch



More information about the Kernel-svn-changes mailing list