From mboxrd@z Thu Jan 1 00:00:00 1970 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) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jul 2018 18:38:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,403,1526367600"; d="scan'208";a="67576599" Received: from debian.sh.intel.com ([10.67.104.228]) by FMSMGA003.fm.intel.com with ESMTP; 25 Jul 2018 18:38:02 -0700 From: Tiwei Bie To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org Cc: lei.a.yao@intel.com Date: Thu, 26 Jul 2018 09:37:20 +0800 Message-Id: <20180726013721.30200-1-tiwei.bie@intel.com> X-Mailer: git-send-email 2.18.0 Subject: [dpdk-dev] [PATCH 1/2] vhost: fix overflow on shadow used ring X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Jul 2018 01:38:21 -0000 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