Add/note KVM security fixes
svn path=/dists/sid/linux-2.6/; revision=18997
This commit is contained in:
parent
c9fee85d35
commit
5f9b292b8a
|
@ -4,6 +4,7 @@ linux-2.6 (3.2.17-1) UNRELEASED; urgency=low
|
||||||
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.17
|
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.17
|
||||||
- md: fix possible corruption of array metadata on shutdown.
|
- md: fix possible corruption of array metadata on shutdown.
|
||||||
- ext4: fix endianness breakage in ext4_split_extent_at()
|
- ext4: fix endianness breakage in ext4_split_extent_at()
|
||||||
|
- KVM: unmap pages from the iommu when slots are removed (CVE-2012-2121)
|
||||||
- btrfs: btrfs_root_readonly() broken on big-endian
|
- btrfs: btrfs_root_readonly() broken on big-endian
|
||||||
- ocfs2: Fix various bugs affecting big-endian architectures
|
- ocfs2: Fix various bugs affecting big-endian architectures
|
||||||
- lockd: fix the endianness bug
|
- lockd: fix the endianness bug
|
||||||
|
@ -31,6 +32,9 @@ linux-2.6 (3.2.17-1) UNRELEASED; urgency=low
|
||||||
* sky2: propogate rx hash when packet is copied
|
* sky2: propogate rx hash when packet is copied
|
||||||
* sky2: fix receive length error in mixed non-VLAN/VLAN traffic
|
* sky2: fix receive length error in mixed non-VLAN/VLAN traffic
|
||||||
(Closes: #492853)
|
(Closes: #492853)
|
||||||
|
* KVM: Ensure all vcpus are consistent with in-kernel irqchip settings
|
||||||
|
(CVE-2012-1601)
|
||||||
|
* KVM: lock slots_lock around device assignment (CVE-2012-2121)
|
||||||
|
|
||||||
[ Bastian Blank ]
|
[ Bastian Blank ]
|
||||||
* [s390] Enable IUCV special message support. (closes: #671238)
|
* [s390] Enable IUCV special message support. (closes: #671238)
|
||||||
|
|
107
debian/patches/bugfix/all/kvm-ensure-all-vcpus-are-consistent-with-in-kernel-irqchip.patch
vendored
Normal file
107
debian/patches/bugfix/all/kvm-ensure-all-vcpus-are-consistent-with-in-kernel-irqchip.patch
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
From: Avi Kivity <avi@redhat.com>
|
||||||
|
Date: Mon, 5 Mar 2012 14:23:29 +0200
|
||||||
|
Subject: [PATCH] KVM: Ensure all vcpus are consistent with in-kernel irqchip
|
||||||
|
settings
|
||||||
|
|
||||||
|
commit 3e515705a1f46beb1c942bb8043c16f8ac7b1e9e upstream.
|
||||||
|
|
||||||
|
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@ellerman.id.au>
|
||||||
|
Signed-off-by: Avi Kivity <avi@redhat.com>
|
||||||
|
---
|
||||||
|
arch/ia64/kvm/kvm-ia64.c | 5 +++++
|
||||||
|
arch/x86/kvm/x86.c | 8 ++++++++
|
||||||
|
include/linux/kvm_host.h | 7 +++++++
|
||||||
|
virt/kvm/kvm_main.c | 4 ++++
|
||||||
|
4 files changed, 24 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
|
||||||
|
index d8ddbba..f5104b7 100644
|
||||||
|
--- a/arch/ia64/kvm/kvm-ia64.c
|
||||||
|
+++ b/arch/ia64/kvm/kvm-ia64.c
|
||||||
|
@@ -1172,6 +1172,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 03a1fd4..9477dc6 100644
|
||||||
|
--- a/arch/x86/kvm/x86.c
|
||||||
|
+++ b/arch/x86/kvm/x86.c
|
||||||
|
@@ -3199,6 +3199,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) {
|
||||||
|
@@ -6107,6 +6110,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 355e445..e42d85a 100644
|
||||||
|
--- a/include/linux/kvm_host.h
|
||||||
|
+++ b/include/linux/kvm_host.h
|
||||||
|
@@ -805,6 +805,13 @@ 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
|
||||||
|
|
||||||
|
#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
|
||||||
|
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
||||||
|
index e4431ad..94e148e 100644
|
||||||
|
--- a/virt/kvm/kvm_main.c
|
||||||
|
+++ b/virt/kvm/kvm_main.c
|
||||||
|
@@ -1651,6 +1651,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
|
||||||
|
goto vcpu_destroy;
|
||||||
|
|
||||||
|
mutex_lock(&kvm->lock);
|
||||||
|
+ if (!kvm_vcpu_compatible(vcpu)) {
|
||||||
|
+ r = -EINVAL;
|
||||||
|
+ goto unlock_vcpu_destroy;
|
||||||
|
+ }
|
||||||
|
if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) {
|
||||||
|
r = -EINVAL;
|
||||||
|
goto unlock_vcpu_destroy;
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
80
debian/patches/bugfix/all/kvm-lock-slots_lock-around-device-assignment.patch
vendored
Normal file
80
debian/patches/bugfix/all/kvm-lock-slots_lock-around-device-assignment.patch
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
From: Alex Williamson <alex.williamson@redhat.com>
|
||||||
|
Date: Tue, 17 Apr 2012 21:46:44 -0600
|
||||||
|
Subject: [PATCH] KVM: lock slots_lock around device assignment
|
||||||
|
|
||||||
|
commit 21a1416a1c945c5aeaeaf791b63c64926018eb77 upstream.
|
||||||
|
|
||||||
|
As pointed out by Jason Baron, when assigning a device to a guest
|
||||||
|
we first set the iommu domain pointer, which enables mapping
|
||||||
|
and unmapping of memory slots to the iommu. This leaves a window
|
||||||
|
where this path is enabled, but we haven't synchronized the iommu
|
||||||
|
mappings to the existing memory slots. Thus a slot being removed
|
||||||
|
at that point could send us down unexpected code paths removing
|
||||||
|
non-existent pinnings and iommu mappings. Take the slots_lock
|
||||||
|
around creating the iommu domain and initial mappings as well as
|
||||||
|
around iommu teardown to avoid this race.
|
||||||
|
|
||||||
|
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
||||||
|
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
|
||||||
|
---
|
||||||
|
virt/kvm/iommu.c | 23 +++++++++++++++--------
|
||||||
|
1 file changed, 15 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
|
||||||
|
index fec1723..e9fff98 100644
|
||||||
|
--- a/virt/kvm/iommu.c
|
||||||
|
+++ b/virt/kvm/iommu.c
|
||||||
|
@@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ mutex_lock(&kvm->slots_lock);
|
||||||
|
+
|
||||||
|
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
|
||||||
|
- if (!kvm->arch.iommu_domain)
|
||||||
|
- return -ENOMEM;
|
||||||
|
+ if (!kvm->arch.iommu_domain) {
|
||||||
|
+ r = -ENOMEM;
|
||||||
|
+ goto out_unlock;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!allow_unsafe_assigned_interrupts &&
|
||||||
|
!iommu_domain_has_cap(kvm->arch.iommu_domain,
|
||||||
|
@@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm)
|
||||||
|
" module option.\n", __func__);
|
||||||
|
iommu_domain_free(kvm->arch.iommu_domain);
|
||||||
|
kvm->arch.iommu_domain = NULL;
|
||||||
|
- return -EPERM;
|
||||||
|
+ r = -EPERM;
|
||||||
|
+ goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = kvm_iommu_map_memslots(kvm);
|
||||||
|
if (r)
|
||||||
|
- goto out_unmap;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
+ kvm_iommu_unmap_memslots(kvm);
|
||||||
|
|
||||||
|
-out_unmap:
|
||||||
|
- kvm_iommu_unmap_memslots(kvm);
|
||||||
|
+out_unlock:
|
||||||
|
+ mutex_unlock(&kvm->slots_lock);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -340,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm)
|
||||||
|
if (!domain)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ mutex_lock(&kvm->slots_lock);
|
||||||
|
kvm_iommu_unmap_memslots(kvm);
|
||||||
|
+ kvm->arch.iommu_domain = NULL;
|
||||||
|
+ mutex_unlock(&kvm->slots_lock);
|
||||||
|
+
|
||||||
|
iommu_domain_free(domain);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
|
@ -195,3 +195,5 @@
|
||||||
+ bugfix/all/nfsv4-revalidate-uid-gid-after-open.patch
|
+ bugfix/all/nfsv4-revalidate-uid-gid-after-open.patch
|
||||||
+ bugfix/all/sky2-propogate-rx-hash-when-packet-is-copied.patch
|
+ bugfix/all/sky2-propogate-rx-hash-when-packet-is-copied.patch
|
||||||
+ bugfix/all/sky2-fix-receive-length-error-in-mixed-non-vlan-vlan.patch
|
+ bugfix/all/sky2-fix-receive-length-error-in-mixed-non-vlan-vlan.patch
|
||||||
|
+ bugfix/all/kvm-ensure-all-vcpus-are-consistent-with-in-kernel-irqchip.patch
|
||||||
|
+ bugfix/all/kvm-lock-slots_lock-around-device-assignment.patch
|
||||||
|
|
Loading…
Reference in New Issue