[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