From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 2B8FC1D7; Fri, 22 Feb 2019 03:45:00 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Feb 2019 18:44:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,397,1544515200"; d="scan'208";a="321102284" Received: from dpdk-tbie.sh.intel.com ([10.67.104.173]) by fmsmga006.fm.intel.com with ESMTP; 21 Feb 2019 18:44:58 -0800 From: Tiwei Bie To: maxime.coquelin@redhat.com, zhihong.wang@intel.com, dev@dpdk.org Cc: stable@dpdk.org Date: Fri, 22 Feb 2019 10:42:07 +0800 Message-Id: <20190222024209.30879-3-tiwei.bie@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190222024209.30879-1-tiwei.bie@intel.com> References: <20190222024209.30879-1-tiwei.bie@intel.com> Subject: [dpdk-stable] [PATCH 2/4] vhost: fix potential use-after-free for zero copy mbuf X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Feb 2019 02:45:00 -0000 Don't free the zero copy mbufs before they have been consumed, otherwise there could be use-after-free. Fixes: b0a985d1f340 ("vhost: add dequeue zero copy") Cc: stable@dpdk.org Signed-off-by: Tiwei Bie --- lib/librte_vhost/vhost.h | 12 ++++++++++++ lib/librte_vhost/vhost_user.c | 3 +++ lib/librte_vhost/virtio_net.c | 12 ------------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index bcfce274b..044651b19 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -757,4 +757,16 @@ restore_mbuf(struct rte_mbuf *m) } } +static __rte_always_inline bool +mbuf_is_consumed(struct rte_mbuf *m) +{ + while (m) { + if (rte_mbuf_refcnt_read(m) > 1) + return false; + m = m->next; + } + + return true; +} + #endif /* _VHOST_NET_CDEV_H_ */ diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index e3ddf2589..6d8253514 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -1218,6 +1218,9 @@ free_zmbufs(struct vhost_virtqueue *vq) zmbuf != NULL; zmbuf = next) { next = TAILQ_NEXT(zmbuf, next); + while (!mbuf_is_consumed(zmbuf->mbuf)) + usleep(1000); + restore_mbuf(zmbuf->mbuf); rte_pktmbuf_free(zmbuf->mbuf); TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next); diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 862ca5e1a..40a292364 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -1306,18 +1306,6 @@ get_zmbuf(struct vhost_virtqueue *vq) return NULL; } -static __rte_always_inline bool -mbuf_is_consumed(struct rte_mbuf *m) -{ - while (m) { - if (rte_mbuf_refcnt_read(m) > 1) - return false; - m = m->next; - } - - return true; -} - static __rte_always_inline uint16_t virtio_dev_tx_split(struct virtio_net *dev, struct vhost_virtqueue *vq, struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count) -- 2.17.1