xen/pci: Allocate memory for physdev_pci_device_add's optarr
authorBoris Ostrovsky <boris.ostrovsky@oracle.com>
Mon, 4 Aug 2014 22:17:23 +0000 (18:17 -0400)
committerDavid Vrabel <david.vrabel@citrix.com>
Thu, 23 Oct 2014 15:24:02 +0000 (16:24 +0100)
physdev_pci_device_add's optarr[] is a zero-sized array and therefore
reference to add.optarr[0] is accessing memory that does not belong to
the 'add' variable.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
drivers/xen/pci.c

index dd9c249ea3118f1e16d05289ff4af766c49d886f..95ee4302ffb860c0fd4f5c948ccf63c3ca9856ef 100644 (file)
@@ -41,24 +41,29 @@ static int xen_add_device(struct device *dev)
 #endif
 
        if (pci_seg_supported) {
-               struct physdev_pci_device_add add = {
-                       .seg = pci_domain_nr(pci_dev->bus),
-                       .bus = pci_dev->bus->number,
-                       .devfn = pci_dev->devfn
+               struct {
+                       struct physdev_pci_device_add add;
+                       uint32_t pxm;
+               } add_ext = {
+                       .add.seg = pci_domain_nr(pci_dev->bus),
+                       .add.bus = pci_dev->bus->number,
+                       .add.devfn = pci_dev->devfn
                };
+               struct physdev_pci_device_add *add = &add_ext.add;
+
 #ifdef CONFIG_ACPI
                acpi_handle handle;
 #endif
 
 #ifdef CONFIG_PCI_IOV
                if (pci_dev->is_virtfn) {
-                       add.flags = XEN_PCI_DEV_VIRTFN;
-                       add.physfn.bus = physfn->bus->number;
-                       add.physfn.devfn = physfn->devfn;
+                       add->flags = XEN_PCI_DEV_VIRTFN;
+                       add->physfn.bus = physfn->bus->number;
+                       add->physfn.devfn = physfn->devfn;
                } else
 #endif
                if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn))
-                       add.flags = XEN_PCI_DEV_EXTFN;
+                       add->flags = XEN_PCI_DEV_EXTFN;
 
 #ifdef CONFIG_ACPI
                handle = ACPI_HANDLE(&pci_dev->dev);
@@ -77,8 +82,8 @@ static int xen_add_device(struct device *dev)
                                status = acpi_evaluate_integer(handle, "_PXM",
                                                               NULL, &pxm);
                                if (ACPI_SUCCESS(status)) {
-                                       add.optarr[0] = pxm;
-                                       add.flags |= XEN_PCI_DEV_PXM;
+                                       add->optarr[0] = pxm;
+                                       add->flags |= XEN_PCI_DEV_PXM;
                                        break;
                                }
                                status = acpi_get_parent(handle, &handle);
@@ -86,7 +91,7 @@ static int xen_add_device(struct device *dev)
                }
 #endif /* CONFIG_ACPI */
 
-               r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, &add);
+               r = HYPERVISOR_physdev_op(PHYSDEVOP_pci_device_add, add);
                if (r != -ENOSYS)
                        return r;
                pci_seg_supported = false;