[kernel] r18845 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/all patches/series
Dann Frazier
dannf at alioth.debian.org
Thu Mar 15 04:02:59 UTC 2012
Author: dannf
Date: Thu Mar 15 04:02:57 2012
New Revision: 18845
Log:
* KVM: Remove ability to assign devices without IOMMU support
* KVM: Check permissions before permitting device assignment (CVE-2011-4347)
Added:
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Device-assignment-permission-checks.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Remove-ability-to-assign-a-device-without-iommu-support.patch
Modified:
dists/squeeze-security/linux-2.6/debian/changelog
dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze1
Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog Wed Mar 14 05:22:01 2012 (r18844)
+++ dists/squeeze-security/linux-2.6/debian/changelog Thu Mar 15 04:02:57 2012 (r18845)
@@ -4,6 +4,8 @@
* ext4: fix undefined behavior in ext4_fill_flex_info() (CVE-2009-4307)
* ecryptfs: Add mount option to check uid of device being mounted =
expect uid (CVE-2011-1833)
+ * KVM: Remove ability to assign devices without IOMMU support
+ * KVM: Check permissions before permitting device assignment (CVE-2011-4347)
[ Ben Hutchings ]
* V4L/DVB: v4l2-ioctl: integer overflow in video_usercopy()
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Device-assignment-permission-checks.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Device-assignment-permission-checks.patch Thu Mar 15 04:02:57 2012 (r18845)
@@ -0,0 +1,139 @@
+commit 3d27e23b17010c668db311140b17bbbb70c78fb9
+Author: Alex Williamson <alex.williamson at redhat.com>
+Date: Tue Dec 20 21:59:09 2011 -0700
+
+ KVM: Device assignment permission checks
+
+ Only allow KVM device assignment to attach to devices which:
+
+ - Are not bridges
+ - Have BAR resources (assume others are special devices)
+ - The user has permissions to use
+
+ Assigning a bridge is a configuration error, it's not supported, and
+ typically doesn't result in the behavior the user is expecting anyway.
+ Devices without BAR resources are typically chipset components that
+ also don't have host drivers. We don't want users to hold such devices
+ captive or cause system problems by fencing them off into an iommu
+ domain. We determine "permission to use" by testing whether the user
+ has access to the PCI sysfs resource files. By default a normal user
+ will not have access to these files, so it provides a good indication
+ that an administration agent has granted the user access to the device.
+
+ [Yang Bai: add missing #include]
+ [avi: fix comment style]
+
+ Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
+ Signed-off-by: Yang Bai <hamo.by at gmail.com>
+ Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+ [dannf: backported to Debian's 2.6.32]
+
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 45ea167..f117640 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -43,6 +43,8 @@
+ #include <linux/swap.h>
+ #include <linux/bitops.h>
+ #include <linux/spinlock.h>
++#include <linux/namei.h>
++#include <linux/fs.h>
+
+ #include <asm/processor.h>
+ #include <asm/io.h>
+@@ -578,12 +580,76 @@ out:
+ return r;
+ }
+
++/*
++ * We want to test whether the caller has been granted permissions to
++ * use this device. To be able to configure and control the device,
++ * the user needs access to PCI configuration space and BAR resources.
++ * These are accessed through PCI sysfs. PCI config space is often
++ * passed to the process calling this ioctl via file descriptor, so we
++ * can't rely on access to that file. We can check for permissions
++ * on each of the BAR resource files, which is a pretty clear
++ * indicator that the user has been granted access to the device.
++ */
++static int probe_sysfs_permissions(struct pci_dev *dev)
++{
++#ifdef CONFIG_SYSFS
++ int i;
++ bool bar_found = false;
++
++ for (i = PCI_STD_RESOURCES; i <= PCI_STD_RESOURCE_END; i++) {
++ char *kpath, *syspath;
++ struct path path;
++ struct inode *inode;
++ int r;
++
++ if (!pci_resource_len(dev, i))
++ continue;
++
++ kpath = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
++ if (!kpath)
++ return -ENOMEM;
++
++ /* Per sysfs-rules, sysfs is always at /sys */
++ syspath = kasprintf(GFP_KERNEL, "/sys%s/resource%d", kpath, i);
++ kfree(kpath);
++ if (!syspath)
++ return -ENOMEM;
++
++ r = kern_path(syspath, LOOKUP_FOLLOW, &path);
++ kfree(syspath);
++ if (r)
++ return r;
++
++ inode = path.dentry->d_inode;
++
++ r = inode_permission(inode, MAY_READ | MAY_WRITE | MAY_ACCESS);
++ path_put(&path);
++ if (r)
++ return r;
++
++ bar_found = true;
++ }
++
++ /* If no resources, probably something special */
++ if (!bar_found)
++ return -EPERM;
++
++ return 0;
++#else
++ return -EINVAL; /* No way to control the device without sysfs */
++#endif
++}
++
+ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+ struct kvm_assigned_pci_dev *assigned_dev)
+ {
+ int r = 0;
+ struct kvm_assigned_dev_kernel *match;
+ struct pci_dev *dev;
++ u8 header_type;
++
++ if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU))
++ return -EINVAL;
+
+ down_read(&kvm->slots_lock);
+ mutex_lock(&kvm->lock);
+@@ -610,6 +676,18 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+ r = -EINVAL;
+ goto out_free;
+ }
++
++ /* Don't allow bridges to be assigned */
++ pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
++ if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) {
++ r = -EPERM;
++ goto out_put;
++ }
++
++ r = probe_sysfs_permissions(dev);
++ if (r)
++ goto out_put;
++
+ if (pci_enable_device(dev)) {
+ printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
+ r = -EBUSY;
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Remove-ability-to-assign-a-device-without-iommu-support.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/KVM-Remove-ability-to-assign-a-device-without-iommu-support.patch Thu Mar 15 04:02:57 2012 (r18845)
@@ -0,0 +1,60 @@
+commit 423873736b78f549fbfa2f715f2e4de7e6c5e1e9
+Author: Alex Williamson <alex.williamson at redhat.com>
+Date: Tue Dec 20 21:59:03 2011 -0700
+
+ KVM: Remove ability to assign a device without iommu support
+
+ This option has no users and it exposes a security hole that we
+ can allow devices to be assigned without iommu protection. Make
+ KVM_DEV_ASSIGN_ENABLE_IOMMU a mandatory option.
+
+ Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
+ Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+ [dannf: backported to Debian's 2.6.32]
+
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4f3434f..45ea167 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -523,6 +523,9 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
+ if (!irqchip_in_kernel(kvm))
+ return r;
+
++ if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU))
++ return -EINVAL;
++
+ mutex_lock(&kvm->lock);
+ r = -ENODEV;
+ match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+@@ -635,16 +638,14 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+
+ list_add(&match->list, &kvm->arch.assigned_dev_head);
+
+- if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
+- if (!kvm->arch.iommu_domain) {
+- r = kvm_iommu_map_guest(kvm);
+- if (r)
+- goto out_list_del;
+- }
+- r = kvm_assign_device(kvm, match);
++ if (!kvm->arch.iommu_domain) {
++ r = kvm_iommu_map_guest(kvm);
+ if (r)
+ goto out_list_del;
+ }
++ r = kvm_assign_device(kvm, match);
++ if (r)
++ goto out_list_del;
+
+ out:
+ mutex_unlock(&kvm->lock);
+@@ -683,8 +684,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
+ goto out;
+ }
+
+- if (match->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU)
+- kvm_deassign_device(kvm, match);
++ kvm_deassign_device(kvm, match);
+
+ kvm_free_assigned_device(kvm, match);
+
Modified: dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze1
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze1 Wed Mar 14 05:22:01 2012 (r18844)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/41squeeze1 Thu Mar 15 04:02:57 2012 (r18845)
@@ -12,3 +12,5 @@
+ bugfix/all/eCryptfs-Make-truncate-path-killable.patch
+ bugfix/all/eCryptfs-Infinite-loop-due-to-overflow-in-ecryptfs_w.patch
+ bugfix/all/cdrom-use-copy_to_user-without-the-underscores.patch
++ bugfix/all/KVM-Remove-ability-to-assign-a-device-without-iommu-support.patch
++ bugfix/all/KVM-Device-assignment-permission-checks.patch
More information about the Kernel-svn-changes
mailing list