rte_pmd_memif_probe() allocates the default MAC address up front and
only hands ownership to the device in memif_create() on success. Every
argument-parsing error jumps to the exit label, which freed the kvargs
but not the MAC address, leaking it. The allocation was also dereferenced
by rte_eth_random_addr() with no check that rte_zmalloc() succeeded, and
was done even in the secondary process which never uses it.
Allocate the MAC address only in the primary process after the secondary
path has returned, check it for NULL, and free it at the exit label on
any failure (on success memif_create() owns it via data->mac_addrs).
Fixes: 09c7e63a71f9 ("net/memif: introduce memory interface PMD")
Cc: [email protected]
Signed-off-by: Sriram Yagnaraman <[email protected]>
---
drivers/net/memif/rte_eth_memif.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/memif/rte_eth_memif.c
b/drivers/net/memif/rte_eth_memif.c
index 24a44d94d7..e8950166b2 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -2239,12 +2239,9 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev)
gid_t owner_gid = -1;
uint32_t flags = 0;
const char *secret = NULL;
- struct rte_ether_addr *ether_addr = rte_zmalloc("",
- sizeof(struct rte_ether_addr), 0);
+ struct rte_ether_addr *ether_addr = NULL;
struct rte_eth_dev *eth_dev;
- rte_eth_random_addr(ether_addr->addr_bytes);
-
MIF_LOG(INFO, "Initialize MEMIF: %s.", name);
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
@@ -2271,7 +2268,7 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev)
if (eth_dev->process_private == NULL) {
MIF_LOG(ERR,
"Failed to alloc memory for process private");
- return -1;
+ return -ENOMEM;
}
rte_eth_dev_probing_finish(eth_dev);
@@ -2279,6 +2276,13 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev)
return 0;
}
+ ether_addr = rte_zmalloc("", sizeof(struct rte_ether_addr), 0);
+ if (ether_addr == NULL) {
+ MIF_LOG(ERR, "Failed to alloc MAC address");
+ return -ENOMEM;
+ }
+ rte_eth_random_addr(ether_addr->addr_bytes);
+
ret = rte_mp_action_register(MEMIF_MP_SEND_REGION,
memif_mp_send_region);
/*
* Primary process can continue probing, but secondary process won't
@@ -2353,6 +2357,12 @@ rte_pmd_memif_probe(struct rte_vdev_device *vdev)
log2_ring_size, pkt_buffer_size, secret, ether_addr);
exit:
+ /*
+ * On success memif_create() takes ownership of ether_addr
+ * (data->mac_addrs); free it on any failure or early exit.
+ */
+ if (ret != 0)
+ rte_free(ether_addr);
rte_kvargs_free(kvlist);
return ret;
}
--
2.43.7