[1/2] vhost: fix overflow on shadow used ring
Checks
Commit Message
The shadow used ring's size is the same as the vq's size,
so we shouldn't try more than "vq size" times. Besides,
the element pointed by avail->idx isn't available to the
device, so we will return error when try "vq size" times.
Fixes: 24e4844048e1 ("vhost: unify Rx mergeable and non-mergeable paths")
Fixes: a922401f35cc ("vhost: add Rx support for packed ring")
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/virtio_net.c | 37 ++++++++++++++++-------------------
1 file changed, 17 insertions(+), 20 deletions(-)
Comments
On Thu, Jul 26, 2018 at 09:37:20AM +0800, Tiwei Bie wrote:
>The shadow used ring's size is the same as the vq's size,
>so we shouldn't try more than "vq size" times. Besides,
>the element pointed by avail->idx isn't available to the
>device, so we will return error when try "vq size" times.
>
>Fixes: 24e4844048e1 ("vhost: unify Rx mergeable and non-mergeable paths")
>Fixes: a922401f35cc ("vhost: add Rx support for packed ring")
>
>Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
>---
> lib/librte_vhost/virtio_net.c | 37 ++++++++++++++++-------------------
> 1 file changed, 17 insertions(+), 20 deletions(-)
>
Reviewed-by: Jens Freimann <jfreiman@redhat.com>
On Thu, Jul 26, 2018 at 09:37:20AM +0800, Tiwei Bie wrote:
> The shadow used ring's size is the same as the vq's size,
> so we shouldn't try more than "vq size" times. Besides,
> the element pointed by avail->idx isn't available to the
> device, so we will return error when try "vq size" times.
>
> Fixes: 24e4844048e1 ("vhost: unify Rx mergeable and non-mergeable paths")
> Fixes: a922401f35cc ("vhost: add Rx support for packed ring")
>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
Series applied to dpdk-next-virtio/master.
@@ -415,13 +415,20 @@ reserve_avail_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
cur_idx = vq->last_avail_idx;
if (rxvq_is_mergeable(dev))
- max_tries = vq->size;
+ max_tries = vq->size - 1;
else
max_tries = 1;
while (size > 0) {
if (unlikely(cur_idx == avail_head))
return -1;
+ /*
+ * if we tried all available ring items, and still
+ * can't get enough buf, it means something abnormal
+ * happened.
+ */
+ if (unlikely(++tries > max_tries))
+ return -1;
if (unlikely(fill_vec_buf_split(dev, vq, cur_idx,
&vec_idx, buf_vec,
@@ -433,16 +440,7 @@ reserve_avail_buf_split(struct virtio_net *dev, struct vhost_virtqueue *vq,
size -= len;
cur_idx++;
- tries++;
*num_buffers += 1;
-
- /*
- * if we tried all available ring items, and still
- * can't get enough buf, it means something abnormal
- * happened.
- */
- if (unlikely(tries > max_tries))
- return -1;
}
*nr_vec = vec_idx;
@@ -582,11 +580,19 @@ reserve_avail_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
avail_idx = vq->last_avail_idx;
if (rxvq_is_mergeable(dev))
- max_tries = vq->size;
+ max_tries = vq->size - 1;
else
max_tries = 1;
while (size > 0) {
+ /*
+ * if we tried all available ring items, and still
+ * can't get enough buf, it means something abnormal
+ * happened.
+ */
+ if (unlikely(++tries > max_tries))
+ return -1;
+
if (unlikely(fill_vec_buf_packed(dev, vq,
avail_idx, &desc_count,
buf_vec, &vec_idx,
@@ -603,16 +609,7 @@ reserve_avail_buf_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
avail_idx -= vq->size;
*nr_descs += desc_count;
- tries++;
*num_buffers += 1;
-
- /*
- * if we tried all available ring items, and still
- * can't get enough buf, it means something abnormal
- * happened.
- */
- if (unlikely(tries > max_tries))
- return -1;
}
*nr_vec = vec_idx;