[dpdk-dev] net/virtio: fix crash on null dereference

Message ID 1468895993-3292-1-git-send-email-yuanhan.liu@linux.intel.com (mailing list archive)
State Accepted, archived
Headers

Commit Message

Yuanhan Liu July 19, 2016, 2:39 a.m. UTC
  The rxq/txq for the queue_release callback could be NULL, say when
rte_eth_dev_configure() fails that the queue is not setup at all.

Do a simple NULL check would fix the crash issue.

Fixes: 01ad44fd374f ("net/virtio: split Rx/Tx queue")

Reported-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
 drivers/net/virtio/virtio_rxtx.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)
  

Comments

Thomas Monjalon July 21, 2016, 10:31 p.m. UTC | #1
2016-07-19 10:39, Yuanhan Liu:
> The rxq/txq for the queue_release callback could be NULL, say when
> rte_eth_dev_configure() fails that the queue is not setup at all.
> 
> Do a simple NULL check would fix the crash issue.
> 
> Fixes: 01ad44fd374f ("net/virtio: split Rx/Tx queue")
> 
> Reported-by: Olivier Matz <olivier.matz@6wind.com>
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>

Applied, thanks
  

Patch

diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index a27208e..2f967de 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -467,13 +467,19 @@  void
 virtio_dev_rx_queue_release(void *rxq)
 {
 	struct virtnet_rx *rxvq = rxq;
-	struct virtqueue *vq = rxvq->vq;
-	/* rxvq is freed when vq is freed, and as mz should be freed after the
+	struct virtqueue *vq;
+	const struct rte_memzone *mz;
+
+	if (rxvq == NULL)
+		return;
+
+	/*
+	 * rxvq is freed when vq is freed, and as mz should be freed after the
 	 * del_queue, so we reserve the mz pointer first.
 	 */
-	const struct rte_memzone *mz = rxvq->mz;
+	vq = rxvq->vq;
+	mz = rxvq->mz;
 
-	/* no need to free rxq as vq and rxq are allocated together */
 	virtio_dev_queue_release(vq);
 	rte_memzone_free(mz);
 }
@@ -553,12 +559,20 @@  void
 virtio_dev_tx_queue_release(void *txq)
 {
 	struct virtnet_tx *txvq = txq;
-	struct virtqueue *vq = txvq->vq;
-	/* txvq is freed when vq is freed, and as mz should be freed after the
+	struct virtqueue *vq;
+	const struct rte_memzone *mz;
+	const struct rte_memzone *hdr_mz;
+
+	if (txvq == NULL)
+		return;
+
+	/*
+	 * txvq is freed when vq is freed, and as mz should be freed after the
 	 * del_queue, so we reserve the mz pointer first.
 	 */
-	const struct rte_memzone *hdr_mz = txvq->virtio_net_hdr_mz;
-	const struct rte_memzone *mz = txvq->mz;
+	vq = txvq->vq;
+	mz = txvq->mz;
+	hdr_mz = txvq->virtio_net_hdr_mz;
 
 	virtio_dev_queue_release(vq);
 	rte_memzone_free(mz);