lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed,  4 Dec 2019 22:25:55 -0500
From:   Yan Zhao <yan.y.zhao@...el.com>
To:     alex.williamson@...hat.com
Cc:     kvm@...r.kernel.org, linux-kernel@...r.kernel.org,
        libvir-list@...hat.com, qemu-devel@...gnu.org, cohuck@...hat.com,
        zhenyuw@...ux.intel.com, zhi.a.wang@...el.com,
        kevin.tian@...el.com, shaopeng.he@...el.com,
        Yan Zhao <yan.y.zhao@...el.com>
Subject: [RFC PATCH 2/9] vfio/pci: test existence before calling region->ops

For regions registered through vfio_pci_register_dev_region(),
before calling region->ops, first check whether region->ops is not null.

As in the next two patches, dev regions of null region->ops are to be
registered by default on behalf of vendor driver, we need to check here
to prevent null pointer access if vendor driver forgets to handle those
dev regions

Cc: Kevin Tian <kevin.tian@...el.com>

Signed-off-by: Yan Zhao <yan.y.zhao@...el.com>
---
 drivers/vfio/pci/vfio_pci.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 55080ff29495..f3730252ee82 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -398,8 +398,12 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
 
 	vdev->virq_disabled = false;
 
-	for (i = 0; i < vdev->num_regions; i++)
+	for (i = 0; i < vdev->num_regions; i++) {
+		if (!vdev->region[i].ops || vdev->region[i].ops->release)
+			continue;
+
 		vdev->region[i].ops->release(vdev, &vdev->region[i]);
+	}
 
 	vdev->num_regions = 0;
 	kfree(vdev->region);
@@ -900,7 +904,8 @@ static long vfio_pci_ioctl(void *device_data,
 			if (ret)
 				return ret;
 
-			if (vdev->region[i].ops->add_capability) {
+			if (vdev->region[i].ops &&
+					vdev->region[i].ops->add_capability) {
 				ret = vdev->region[i].ops->add_capability(vdev,
 						&vdev->region[i], &caps);
 				if (ret)
@@ -1251,6 +1256,9 @@ static ssize_t vfio_pci_rw(void *device_data, char __user *buf,
 		return vfio_pci_vga_rw(vdev, buf, count, ppos, iswrite);
 	default:
 		index -= VFIO_PCI_NUM_REGIONS;
+		if (!vdev->region[index].ops || !vdev->region[index].ops->rw)
+			return -EINVAL;
+
 		return vdev->region[index].ops->rw(vdev, buf,
 						   count, ppos, iswrite);
 	}
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ