Xuan Zhuo
2023-Oct-08 07:45 UTC
[PATCH vhost v1 0/2] strictly check the acccess to the common cfg
1. fix the length of the pci_iomap_range() to the common cfg 2. add size check for the vq-reset 3. add build size check to the new common cfg items Xuan Zhuo (2): virtio_pci: fix the common map size and add check for vq-reset virtio_pci: add build offset check for the new common cfg items drivers/virtio/virtio_pci_modern_dev.c | 31 ++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) -- 2.32.0.3.g01195cf9f
Xuan Zhuo
2023-Oct-08 07:45 UTC
[PATCH vhost v1 1/2] virtio_pci: fix the common map size and add check for vq-reset
Now, the function vp_modern_map_capability() takes the size parameter,
which corresponds to the size of virtio_pci_common_cfg. As a result,
this indicates the size of memory area to map.
However, if the _F_RING_RESET is negotiated, the extra items will be
used. Therefore, we need to use the size of virtio_pci_modre_common_cfg
to map more space.
Meanwhile, this patch checks the common cfg size when _F_RING_ERSET is
negotiated.
Signed-off-by: Xuan Zhuo <xuanzhuo at linux.alibaba.com>
---
drivers/virtio/virtio_pci_modern_dev.c | 27 ++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio_pci_modern_dev.c
b/drivers/virtio/virtio_pci_modern_dev.c
index aad7d9296e77..45d41e6c7799 100644
--- a/drivers/virtio/virtio_pci_modern_dev.c
+++ b/drivers/virtio/virtio_pci_modern_dev.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/virtio_pci_modern.h>
+#include <linux/virtio_config.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -142,6 +143,22 @@ static inline int virtio_pci_find_capability(struct pci_dev
*dev, u8 cfg_type,
return 0;
}
+static inline int check_common_size(struct virtio_pci_modern_device *mdev,
+ size_t common_len)
+{
+ u64 features;
+
+ features = vp_modern_get_features(mdev);
+
+ if (features & BIT_ULL(VIRTIO_F_RING_RESET)) {
+ if (unlikely(common_len < offsetofend(struct virtio_pci_modern_common_cfg,
+ queue_reset)))
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
/* This is part of the ABI. Don't screw with it. */
static inline void check_offsets(void)
{
@@ -218,6 +235,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev)
int err, common, isr, notify, device;
u32 notify_length;
u32 notify_offset;
+ size_t common_len;
int devid;
check_offsets();
@@ -291,10 +309,14 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev)
err = -EINVAL;
mdev->common = vp_modern_map_capability(mdev, common,
sizeof(struct virtio_pci_common_cfg), 4,
- 0, sizeof(struct virtio_pci_common_cfg),
- NULL, NULL);
+ 0, sizeof(struct virtio_pci_modern_common_cfg),
+ &common_len, NULL);
if (!mdev->common)
goto err_map_common;
+
+ if (check_common_size(mdev, common_len))
+ goto err_common_size;
+
mdev->isr = vp_modern_map_capability(mdev, isr, sizeof(u8), 1,
0, 1,
NULL, NULL);
@@ -353,6 +375,7 @@ int vp_modern_probe(struct virtio_pci_modern_device *mdev)
err_map_notify:
pci_iounmap(pci_dev, mdev->isr);
err_map_isr:
+err_common_size:
pci_iounmap(pci_dev, mdev->common);
err_map_common:
pci_release_selected_regions(pci_dev, mdev->modern_bars);
--
2.32.0.3.g01195cf9f
Xuan Zhuo
2023-Oct-08 07:45 UTC
[PATCH vhost v1 2/2] virtio_pci: add build offset check for the new common cfg items
Add checks to the check_offsets(void) for queue_notify_data and queue_reset. Signed-off-by: Xuan Zhuo <xuanzhuo at linux.alibaba.com> Acked-by: Jason Wang <jasowang at redhat.com> --- drivers/virtio/virtio_pci_modern_dev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c index 45d41e6c7799..3a49bc963a71 100644 --- a/drivers/virtio/virtio_pci_modern_dev.c +++ b/drivers/virtio/virtio_pci_modern_dev.c @@ -220,6 +220,10 @@ static inline void check_offsets(void) offsetof(struct virtio_pci_common_cfg, queue_used_lo)); BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_USEDHI ! offsetof(struct virtio_pci_common_cfg, queue_used_hi)); + BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_NDATA !+ offsetof(struct virtio_pci_modern_common_cfg, queue_notify_data)); + BUILD_BUG_ON(VIRTIO_PCI_COMMON_Q_RESET !+ offsetof(struct virtio_pci_modern_common_cfg, queue_reset)); } /* -- 2.32.0.3.g01195cf9f