A malicious guest may easily forge some illegal vring desc buf.
To make our vhost robust, we need make sure desc->next will not
go beyond the vq->desc[] array.

Suggested-by: Rich Lane <rich.lane at bigswitch.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu at linux.intel.com>
---
 lib/librte_vhost/vhost_rxtx.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index c2adcd9..b0c0c94 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -148,6 +148,8 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
                                /* Room in vring buffer is not enough */
                                return -1;
                        }
+                       if (unlikely(desc->next >= vq->size))
+                               return -1;

                        desc = &vq->desc[desc->next];
                        desc_addr   = gpa_to_vva(dev, desc->addr);
@@ -302,7 +304,7 @@ fill_vec_buf(struct vhost_virtqueue *vq, uint32_t avail_idx,
        uint32_t len    = *allocated;

        while (1) {
-               if (vec_id >= BUF_VECTOR_MAX)
+               if (unlikely(vec_id >= BUF_VECTOR_MAX || idx >= vq->size))
                        return -1;

                len += vq->desc[idx].len;
@@ -671,6 +673,8 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
        while (desc_avail || (desc->flags & VRING_DESC_F_NEXT) != 0) {
                /* This desc reachs to its end, get the next one */
                if (desc_avail == 0) {
+                       if (unlikely(desc->next >= vq->size))
+                               goto fail;
                        desc = &vq->desc[desc->next];

                        desc_addr = gpa_to_vva(dev, desc->addr);
@@ -691,9 +695,7 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
                        if (unlikely(!cur)) {
                                RTE_LOG(ERR, VHOST_DATA, "Failed to "
                                        "allocate memory for mbuf.\n");
-                               if (head)
-                                       rte_pktmbuf_free(head);
-                               return NULL;
+                               goto fail;
                        }
                        if (!head) {
                                head = cur;
@@ -729,6 +731,11 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
        }

        return head;
+
+fail:
+       if (head)
+               rte_pktmbuf_free(head);
+       return NULL;
 }

 uint16_t
-- 
1.9.0

Reply via email to