From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tiwei Bie Subject: [PATCH 1/2] vhost: fix overflow on shadow used ring Date: Thu, 26 Jul 2018 09:37:20 +0800 Message-ID: <20180726013721.30200-1-tiwei.bie@intel.com> Cc: lei.a.yao@intel.com To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org Return-path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 065DF1C01 for ; Thu, 26 Jul 2018 03:38:20 +0200 (CEST) List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- lib/librte_vhost/virtio_net.c | 37 ++++++++++++++++------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 5d4b97587..3b11b353c 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -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; -- 2.18.0