From 3400148949ea4edecba0256f4ab97e80f1d98474 Mon Sep 17 00:00:00 2001 From: Yunjian Wang Date: Mon, 6 Jul 2020 20:27:51 +0800 Subject: [PATCH] net/af_packet: fix memory leak on init failure Add missing code to free memory when the device initialization fails. Fixes: ccd37d341e8d ("net/af_packet: remove queue number limitation") Fixes: 5f19dee604ed ("drivers/net: do not use private ethdev data") Cc: stable@dpdk.org Signed-off-by: Yunjian Wang Reviewed-by: Ferruh Yigit --- drivers/net/af_packet/rte_eth_af_packet.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index db5de8e45e..62945fee20 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -637,9 +637,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, sizeof(struct pkt_tx_queue), 0, numa_node); if (!(*internals)->rx_queue || !(*internals)->tx_queue) { - rte_free((*internals)->rx_queue); - rte_free((*internals)->tx_queue); - return -1; + goto free_internals; } for (q = 0; q < nb_queues; q++) { @@ -664,20 +662,20 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG(ERR, "%s: I/F name too long (%s)", name, pair->value); - return -1; + goto free_internals; } if (ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1) { PMD_LOG_ERRNO(ERR, "%s: ioctl failed (SIOCGIFINDEX)", name); - return -1; + goto free_internals; } (*internals)->if_name = strdup(pair->value); if ((*internals)->if_name == NULL) - return -1; + goto free_internals; (*internals)->if_index = ifr.ifr_ifindex; if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1) { PMD_LOG_ERRNO(ERR, "%s: ioctl failed (SIOCGIFHWADDR)", name); - return -1; + goto free_internals; } memcpy(&(*internals)->eth_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); @@ -701,7 +699,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, PMD_LOG_ERRNO(ERR, "%s: could not open AF_PACKET socket", name); - return -1; + goto error; } tpver = TPACKET_V2; @@ -854,6 +852,9 @@ error: ((*internals)->rx_queue[q].sockfd != qsockfd)) close((*internals)->rx_queue[q].sockfd); } +free_internals: + rte_free((*internals)->rx_queue); + rte_free((*internals)->tx_queue); free((*internals)->if_name); rte_free(*internals); return -1; -- 2.20.1