]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
vfio/pci: Add device denylist
authorGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Mon, 27 Jul 2020 19:43:40 +0000 (13:43 -0600)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 27 Jul 2020 19:43:40 +0000 (13:43 -0600)
Add denylist of devices that by default are not probed by vfio-pci.
Devices in this list may be susceptible to untrusted application, even
if the IOMMU is enabled. To be accessed via vfio-pci, the user has to
explicitly disable the denylist.

The denylist can be disabled via the module parameter disable_denylist.

Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/vfio_pci.c

index dabca0450e6dc751670b3107467ace2eb19718ff..f368a3993ac14b1882280166f19de75591cf9d69 100644 (file)
@@ -60,6 +60,10 @@ module_param(enable_sriov, bool, 0644);
 MODULE_PARM_DESC(enable_sriov, "Enable support for SR-IOV configuration.  Enabling SR-IOV on a PF typically requires support of the userspace PF driver, enabling VFs without such support may result in non-functional VFs or PF.");
 #endif
 
+static bool disable_denylist;
+module_param(disable_denylist, bool, 0444);
+MODULE_PARM_DESC(disable_denylist, "Disable use of device denylist. Disabling the denylist allows binding to devices with known errata that may lead to exploitable stability or security issues when accessed by untrusted users.");
+
 static inline bool vfio_vga_disabled(void)
 {
 #ifdef CONFIG_VFIO_PCI_VGA
@@ -69,6 +73,29 @@ static inline bool vfio_vga_disabled(void)
 #endif
 }
 
+static bool vfio_pci_dev_in_denylist(struct pci_dev *pdev)
+{
+       return false;
+}
+
+static bool vfio_pci_is_denylisted(struct pci_dev *pdev)
+{
+       if (!vfio_pci_dev_in_denylist(pdev))
+               return false;
+
+       if (disable_denylist) {
+               pci_warn(pdev,
+                        "device denylist disabled - allowing device %04x:%04x.\n",
+                        pdev->vendor, pdev->device);
+               return false;
+       }
+
+       pci_warn(pdev, "%04x:%04x exists in vfio-pci device denylist, driver probing disallowed.\n",
+                pdev->vendor, pdev->device);
+
+       return true;
+}
+
 /*
  * Our VGA arbiter participation is limited since we don't know anything
  * about the device itself.  However, if the device is the only VGA device
@@ -1856,6 +1883,9 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        struct iommu_group *group;
        int ret;
 
+       if (vfio_pci_is_denylisted(pdev))
+               return -EINVAL;
+
        if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
                return -EINVAL;
 
@@ -2345,6 +2375,9 @@ static int __init vfio_pci_init(void)
 
        vfio_pci_fill_ids();
 
+       if (disable_denylist)
+               pr_warn("device denylist disabled.\n");
+
        return 0;
 
 out_driver: