[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