drivers/net/ethernet/broadcom/bnxt/bnxt.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
In bnxt_alloc_mem(), the function allocates memory for bp->bnapi,
bp->rx_ring, bp->tx_ring, and bp->tx_ring_map.
However, if the allocation for rx_ring, tx_ring, or tx_ring_map fails, the
function currently returns -ENOMEM directly without freeing the previously
allocated memory. This leads to a memory leak.
Fix this by jumping to the alloc_mem_err label when allocation fails,
which ensures that bnxt_free_mem() is called to properly release all
allocated resources.
Compile tested only. Issue found using a prototype static analysis tool
and code review.
Fixes: a960dec98861 ("bnxt_en: Add tx ring mapping logic.")
Fixes: b6ab4b01f53b ("bnxt_en: Separate bnxt_{rx|tx}_ring_info structs from bnxt_napi struct.")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 8419d1eb4035..99dae75146b5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5491,8 +5491,10 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
bp->rx_ring = kcalloc(bp->rx_nr_rings,
sizeof(struct bnxt_rx_ring_info),
GFP_KERNEL);
- if (!bp->rx_ring)
- return -ENOMEM;
+ if (!bp->rx_ring) {
+ rc = -ENOMEM;
+ goto alloc_mem_err;
+ }
for (i = 0; i < bp->rx_nr_rings; i++) {
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
@@ -5512,14 +5514,18 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
bp->tx_ring = kcalloc(bp->tx_nr_rings,
sizeof(struct bnxt_tx_ring_info),
GFP_KERNEL);
- if (!bp->tx_ring)
- return -ENOMEM;
+ if (!bp->tx_ring) {
+ rc = -ENOMEM;
+ goto alloc_mem_err;
+ }
bp->tx_ring_map = kcalloc(bp->tx_nr_rings, sizeof(u16),
GFP_KERNEL);
- if (!bp->tx_ring_map)
- return -ENOMEM;
+ if (!bp->tx_ring_map) {
+ rc = -ENOMEM;
+ goto alloc_mem_err;
+ }
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
j = 0;
--
2.34.1
On Thu, Jan 22, 2026 at 2:56 PM Zilin Guan <zilin@seu.edu.cn> wrote:
>
> In bnxt_alloc_mem(), the function allocates memory for bp->bnapi,
> bp->rx_ring, bp->tx_ring, and bp->tx_ring_map.
>
> However, if the allocation for rx_ring, tx_ring, or tx_ring_map fails, the
> function currently returns -ENOMEM directly without freeing the previously
> allocated memory. This leads to a memory leak.
>
> Fix this by jumping to the alloc_mem_err label when allocation fails,
> which ensures that bnxt_free_mem() is called to properly release all
> allocated resources.
This fix is not needed. The memory is freed by the caller of bnxt_alloc_mem().
>
> Compile tested only. Issue found using a prototype static analysis tool
> and code review.
>
> Fixes: a960dec98861 ("bnxt_en: Add tx ring mapping logic.")
> Fixes: b6ab4b01f53b ("bnxt_en: Separate bnxt_{rx|tx}_ring_info structs from bnxt_napi struct.")
> Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
> ---
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index 8419d1eb4035..99dae75146b5 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -5491,8 +5491,10 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
> bp->rx_ring = kcalloc(bp->rx_nr_rings,
> sizeof(struct bnxt_rx_ring_info),
> GFP_KERNEL);
> - if (!bp->rx_ring)
> - return -ENOMEM;
> + if (!bp->rx_ring) {
> + rc = -ENOMEM;
> + goto alloc_mem_err;
> + }
>
> for (i = 0; i < bp->rx_nr_rings; i++) {
> struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
> @@ -5512,14 +5514,18 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
> bp->tx_ring = kcalloc(bp->tx_nr_rings,
> sizeof(struct bnxt_tx_ring_info),
> GFP_KERNEL);
> - if (!bp->tx_ring)
> - return -ENOMEM;
> + if (!bp->tx_ring) {
> + rc = -ENOMEM;
> + goto alloc_mem_err;
> + }
>
> bp->tx_ring_map = kcalloc(bp->tx_nr_rings, sizeof(u16),
> GFP_KERNEL);
>
> - if (!bp->tx_ring_map)
> - return -ENOMEM;
> + if (!bp->tx_ring_map) {
> + rc = -ENOMEM;
> + goto alloc_mem_err;
> + }
>
> if (bp->flags & BNXT_FLAG_SHARED_RINGS)
> j = 0;
> --
> 2.34.1
>
On Thu, Jan 22, 2026 at 03:14:08PM +0530, Pavan Chebbi wrote: > On Thu, Jan 22, 2026 at 2:56 PM Zilin Guan <zilin@seu.edu.cn> wrote: > > > > In bnxt_alloc_mem(), the function allocates memory for bp->bnapi, > > bp->rx_ring, bp->tx_ring, and bp->tx_ring_map. > > > > However, if the allocation for rx_ring, tx_ring, or tx_ring_map fails, the > > function currently returns -ENOMEM directly without freeing the previously > > allocated memory. This leads to a memory leak. > > > > Fix this by jumping to the alloc_mem_err label when allocation fails, > > which ensures that bnxt_free_mem() is called to properly release all > > allocated resources. > > This fix is not needed. The memory is freed by the caller of bnxt_alloc_mem(). That is an anti-pattern as well. On error, the function should clean up all resources it allocated. Thanks
On Thu, Jan 22, 2026 at 03:14:08PM +0530, Pavan Chebbi wrote: > On Thu, Jan 22, 2026 at 2:56 PM Zilin Guan <zilin@seu.edu.cn> wrote: > > > > In bnxt_alloc_mem(), the function allocates memory for bp->bnapi, > > bp->rx_ring, bp->tx_ring, and bp->tx_ring_map. > > > > However, if the allocation for rx_ring, tx_ring, or tx_ring_map fails, the > > function currently returns -ENOMEM directly without freeing the previously > > allocated memory. This leads to a memory leak. > > > > Fix this by jumping to the alloc_mem_err label when allocation fails, > > which ensures that bnxt_free_mem() is called to properly release all > > allocated resources. > > This fix is not needed. The memory is freed by the caller of bnxt_alloc_mem(). Hi Pavan, Thank you for your review and clarification. I observed that most allocation failure paths in bnxt_alloc_mem() jump to alloc_mem_err for error handling, which led me to incorrectly assume that this function was strictly responsible for cleaning up its own allocated memory upon failure. I failed to realize that the caller also handles the cleanup for these specific cases. Thanks for pointing this out. Sorry for the noise. Best regards, Zilin Guan
© 2016 - 2026 Red Hat, Inc.