tap_tx_queue_release() reads dev->data->rx_queues[qid] to find out whether
the queue file descriptor is still shared with the Rx side. When ethdev
tears both queue arrays down it releases the Rx queues first and frees
dev->data->rx_queues, so the Tx release dereferences a NULL array and the
process crashes.
Both ethdev call sites do that: the reset_queues error path of
rte_eth_dev_configure(), reached whenever the driver rejects a
reconfigure, and rte_eth_dev_internal_reset(), which bonding calls
unconditionally when a member port is removed.
Treat a freed Rx array like an already released Rx queue and close the
file descriptor. tap_rx_queue_release() reads dev->data->tx_queues the
same way; that array is always still allocated when it runs, but guard it
too so both paths stay symmetric.
Fixes: 72ab1dc1598e ("net/tap: do not duplicate file descriptors")
Cc: [email protected]
Signed-off-by: Maxime Leroy <[email protected]>
---
drivers/net/tap/rte_eth_tap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index b93452f168..eec18a7c97 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -1170,7 +1170,7 @@ tap_rx_queue_release(struct rte_eth_dev *dev, uint16_t
qid)
tap_rxq_pool_free(rxq->pool);
- if (dev->data->tx_queues[qid] == NULL)
+ if (dev->data->tx_queues == NULL || dev->data->tx_queues[qid] == NULL)
tap_queue_close(process_private, qid);
rte_free(rxq);
@@ -1187,7 +1187,7 @@ tap_tx_queue_release(struct rte_eth_dev *dev, uint16_t
qid)
return;
process_private = rte_eth_devices[txq->out_port].process_private;
- if (dev->data->rx_queues[qid] == NULL)
+ if (dev->data->rx_queues == NULL || dev->data->rx_queues[qid] == NULL)
tap_queue_close(process_private, qid);
rte_free(txq);
--
2.43.0