summaryrefslogtreecommitdiff
path: root/drivers/virtio/virtio_pci_modern.c
diff options
context:
space:
mode:
authorKeir Fraser <keirf@google.com>2022-03-23 17:07:27 +0300
committerMichael S. Tsirkin <mst@redhat.com>2022-03-28 23:52:59 +0300
commit3f63a1d7f6f500b6891b1003cec3e23ea4996a2e (patch)
tree2615cc453c0a7999244092a05c1dfe7f8a62c095 /drivers/virtio/virtio_pci_modern.c
parenteb4cecb453a19b34d5454b49532e09e9cb0c1529 (diff)
downloadlinux-3f63a1d7f6f500b6891b1003cec3e23ea4996a2e.tar.xz
virtio: pci: check bar values read from virtio config space
virtio pci config structures may in future have non-standard bar values in the bar field. We should anticipate this by skipping any structures containing such a reserved value. The bar value should never change: check for harmful modified values we re-read it from the config space in vp_modern_map_capability(). Also clean up an existing check to consistently use PCI_STD_NUM_BARS. Signed-off-by: Keir Fraser <keirf@google.com> Link: https://lore.kernel.org/r/20220323140727.3499235-1-keirf@google.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/virtio/virtio_pci_modern.c')
-rw-r--r--drivers/virtio/virtio_pci_modern.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 30654d3a0b41..a2671a20ef77 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -293,7 +293,7 @@ static int virtio_pci_find_shm_cap(struct pci_dev *dev, u8 required_id,
for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); pos > 0;
pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) {
- u8 type, cap_len, id;
+ u8 type, cap_len, id, res_bar;
u32 tmp32;
u64 res_offset, res_length;
@@ -315,9 +315,14 @@ static int virtio_pci_find_shm_cap(struct pci_dev *dev, u8 required_id,
if (id != required_id)
continue;
- /* Type, and ID match, looks good */
pci_read_config_byte(dev, pos + offsetof(struct virtio_pci_cap,
- bar), bar);
+ bar), &res_bar);
+ if (res_bar >= PCI_STD_NUM_BARS)
+ continue;
+
+ /* Type and ID match, and the BAR value isn't reserved.
+ * Looks good.
+ */
/* Read the lower 32bit of length and offset */
pci_read_config_dword(dev, pos + offsetof(struct virtio_pci_cap,
@@ -337,6 +342,7 @@ static int virtio_pci_find_shm_cap(struct pci_dev *dev, u8 required_id,
length_hi), &tmp32);
res_length |= ((u64)tmp32) << 32;
+ *bar = res_bar;
*offset = res_offset;
*len = res_length;