From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id D77E91B439 for ; Fri, 4 Jan 2019 05:09:20 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Jan 2019 20:09:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,437,1539673200"; d="scan'208";a="288727283" Received: from dpdk-tbie.sh.intel.com ([10.67.104.173]) by orsmga005.jf.intel.com with ESMTP; 03 Jan 2019 20:09:19 -0800 From: Tiwei Bie To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org Date: Fri, 4 Jan 2019 12:06:39 +0800 Message-Id: <20190104040642.27463-4-tiwei.bie@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190104040642.27463-1-tiwei.bie@intel.com> References: <20190104040642.27463-1-tiwei.bie@intel.com> Subject: [dpdk-dev] [PATCH 3/6] vhost: fix possible dead loop in relay helpers 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: Fri, 04 Jan 2019 04:09:21 -0000 Fix a possible dead loop which may happen, e.g. when driver created a loop in the desc list. Fixes: b13ad2decc83 ("vhost: provide helpers for virtio ring relay") Signed-off-by: Tiwei Bie --- lib/librte_vhost/vdpa.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c index 407d1c363..02083bb8a 100644 --- a/lib/librte_vhost/vdpa.c +++ b/lib/librte_vhost/vdpa.c @@ -157,6 +157,7 @@ rte_vdpa_relay_vring_avail(int vid, uint16_t qid, void *vring_m) struct vring_desc *idesc = NULL; struct vring *s_vring; uint64_t dlen; + uint32_t nr_descs; int ret; uint8_t perm; @@ -183,9 +184,14 @@ rte_vdpa_relay_vring_avail(int vid, uint16_t qid, void *vring_m) s_vring->avail->ring[idx_m & (vq->size - 1)] = desc_id; desc_ring = vq->desc; + nr_descs = vq->size; if (vq->desc[desc_id].flags & VRING_DESC_F_INDIRECT) { dlen = vq->desc[desc_id].len; + nr_descs = dlen / sizeof(struct vring_desc); + if (unlikely(nr_descs > vq->size)) + return -1; + desc_ring = (struct vring_desc *)(uintptr_t) vhost_iova_to_vva(dev, vq, vq->desc[desc_id].addr, &dlen, @@ -210,6 +216,8 @@ rte_vdpa_relay_vring_avail(int vid, uint16_t qid, void *vring_m) do { if (unlikely(desc_id >= vq->size)) goto fail; + if (unlikely(nr_descs-- == 0)) + goto fail; desc = desc_ring[desc_id]; perm = desc.flags & VRING_DESC_F_WRITE ? VHOST_ACCESS_WO : VHOST_ACCESS_RO; @@ -252,6 +260,7 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m) struct vring_desc *idesc = NULL; struct vring *s_vring; uint64_t dlen; + uint32_t nr_descs; int ret; if (!dev || !vring_m) @@ -276,12 +285,17 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m) desc_id = vq->used->ring[idx & (vq->size - 1)].id; desc_ring = vq->desc; + nr_descs = vq->size; if (unlikely(desc_id >= vq->size)) return -1; if (vq->desc[desc_id].flags & VRING_DESC_F_INDIRECT) { dlen = vq->desc[desc_id].len; + nr_descs = dlen / sizeof(struct vring_desc); + if (unlikely(nr_descs > vq->size)) + return -1; + desc_ring = (struct vring_desc *)(uintptr_t) vhost_iova_to_vva(dev, vq, vq->desc[desc_id].addr, &dlen, @@ -306,6 +320,8 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m) do { if (unlikely(desc_id >= vq->size)) goto fail; + if (unlikely(nr_descs-- == 0)) + goto fail; desc = desc_ring[desc_id]; if (desc.flags & VRING_DESC_F_WRITE) vhost_log_write(dev, desc.addr, desc.len); -- 2.17.1