Browse Source

Merge tag 'vfio-v4.10-rc4' of git://github.com/awilliam/linux-vfio

Pull VFIO fixes from Alex Williamson:

 - Cleanups and bug fixes for the mtty sample driver (Dan Carpenter)

 - Export and make use of has_capability() to fix incorrect use of
   ns_capable() for testing task capabilities (Jike Song)

* tag 'vfio-v4.10-rc4' of git://github.com/awilliam/linux-vfio:
  vfio/type1: Remove pid_namespace.h include
  vfio iommu type1: fix the testing of capability for remote task
  capability: export has_capability
  vfio-mdev: remove some dead code
  vfio-mdev: buffer overflow in ioctl()
  vfio-mdev: return -EFAULT if copy_to_user() fails
Linus Torvalds 8 years ago
parent
commit
af54efa4f5
3 changed files with 18 additions and 10 deletions
  1. 1 3
      drivers/vfio/vfio_iommu_type1.c
  2. 1 0
      kernel/capability.c
  3. 16 7
      samples/vfio-mdev/mtty.c

+ 1 - 3
drivers/vfio/vfio_iommu_type1.c

@@ -36,7 +36,6 @@
 #include <linux/uaccess.h>
 #include <linux/uaccess.h>
 #include <linux/vfio.h>
 #include <linux/vfio.h>
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
-#include <linux/pid_namespace.h>
 #include <linux/mdev.h>
 #include <linux/mdev.h>
 #include <linux/notifier.h>
 #include <linux/notifier.h>
 
 
@@ -495,8 +494,7 @@ static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr,
 				  unsigned long *pfn_base, bool do_accounting)
 				  unsigned long *pfn_base, bool do_accounting)
 {
 {
 	unsigned long limit;
 	unsigned long limit;
-	bool lock_cap = ns_capable(task_active_pid_ns(dma->task)->user_ns,
-				   CAP_IPC_LOCK);
+	bool lock_cap = has_capability(dma->task, CAP_IPC_LOCK);
 	struct mm_struct *mm;
 	struct mm_struct *mm;
 	int ret;
 	int ret;
 	bool rsvd;
 	bool rsvd;

+ 1 - 0
kernel/capability.c

@@ -318,6 +318,7 @@ bool has_capability(struct task_struct *t, int cap)
 {
 {
 	return has_ns_capability(t, &init_user_ns, cap);
 	return has_ns_capability(t, &init_user_ns, cap);
 }
 }
+EXPORT_SYMBOL(has_capability);
 
 
 /**
 /**
  * has_ns_capability_noaudit - Does a task have a capability (unaudited)
  * has_ns_capability_noaudit - Does a task have a capability (unaudited)

+ 16 - 7
samples/vfio-mdev/mtty.c

@@ -1073,7 +1073,7 @@ int mtty_get_region_info(struct mdev_device *mdev,
 {
 {
 	unsigned int size = 0;
 	unsigned int size = 0;
 	struct mdev_state *mdev_state;
 	struct mdev_state *mdev_state;
-	int bar_index;
+	u32 bar_index;
 
 
 	if (!mdev)
 	if (!mdev)
 		return -EINVAL;
 		return -EINVAL;
@@ -1082,8 +1082,11 @@ int mtty_get_region_info(struct mdev_device *mdev,
 	if (!mdev_state)
 	if (!mdev_state)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	mutex_lock(&mdev_state->ops_lock);
 	bar_index = region_info->index;
 	bar_index = region_info->index;
+	if (bar_index >= VFIO_PCI_NUM_REGIONS)
+		return -EINVAL;
+
+	mutex_lock(&mdev_state->ops_lock);
 
 
 	switch (bar_index) {
 	switch (bar_index) {
 	case VFIO_PCI_CONFIG_REGION_INDEX:
 	case VFIO_PCI_CONFIG_REGION_INDEX:
@@ -1180,7 +1183,10 @@ static long mtty_ioctl(struct mdev_device *mdev, unsigned int cmd,
 
 
 		memcpy(&mdev_state->dev_info, &info, sizeof(info));
 		memcpy(&mdev_state->dev_info, &info, sizeof(info));
 
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		if (copy_to_user((void __user *)arg, &info, minsz))
+			return -EFAULT;
+
+		return 0;
 	}
 	}
 	case VFIO_DEVICE_GET_REGION_INFO:
 	case VFIO_DEVICE_GET_REGION_INFO:
 	{
 	{
@@ -1201,7 +1207,10 @@ static long mtty_ioctl(struct mdev_device *mdev, unsigned int cmd,
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		if (copy_to_user((void __user *)arg, &info, minsz))
+			return -EFAULT;
+
+		return 0;
 	}
 	}
 
 
 	case VFIO_DEVICE_GET_IRQ_INFO:
 	case VFIO_DEVICE_GET_IRQ_INFO:
@@ -1221,10 +1230,10 @@ static long mtty_ioctl(struct mdev_device *mdev, unsigned int cmd,
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 
 
-		if (info.count == -1)
-			return -EINVAL;
+		if (copy_to_user((void __user *)arg, &info, minsz))
+			return -EFAULT;
 
 
-		return copy_to_user((void __user *)arg, &info, minsz);
+		return 0;
 	}
 	}
 	case VFIO_DEVICE_SET_IRQS:
 	case VFIO_DEVICE_SET_IRQS:
 	{
 	{