Thread (2 messages) 2 messages, 2 authors, 7d ago

Re: [PATCH net] gianfar: fix memory leak in gfar_parse_group error paths

From: Pavan Chebbi <pavan.chebbi@broadcom.com>
Date: 2026-06-22 04:08:59
Also in: lkml

On Mon, Jun 22, 2026 at 7:49 AM Rosen Penev [off-list ref] wrote:
quoted hunk ↗ jump to hunk
In gfar_parse_group, if any allocation in the irqinfo[] loop fails,
or if of_iomap fails, or if the IRQ parsing fails, the already-
allocated irqinfo[] entries and mapped regs are not freed.  The
caller's free_gfar_dev cannot clean them up because priv->num_grps
is only incremented after a successful return.

Fix by adding an err_out label that frees all successfully allocated
irqinfo entries and unmaps regs if mapped.  Track the number of
allocated entries with 'allocated' and propagate the correct error
code.

Fixes: 46ceb60ca80fa ("gianfar: Add Multiple group Support")
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <redacted>
---
 drivers/net/ethernet/freescale/gianfar.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 3271de5844f84..12ebb207be0be 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -502,17 +502,19 @@ static int gfar_parse_group(struct device_node *np,
                            struct gfar_private *priv, const char *model)
 {
        struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
-       int i;
+       int err = -ENOMEM;
+       int i, allocated = 0;
Declarations should follow reverse xmas-tree fashion.
BTW, why num_grps cannot be incremented quicker? Not sure it can cause
any issues, since all this is happening probe(), it should be safe to
do that?
That way you could avoid cleaning up at two different places...
quoted hunk ↗ jump to hunk
        for (i = 0; i < GFAR_NUM_IRQS; i++) {
                grp->irqinfo[i] = kzalloc_obj(struct gfar_irqinfo);
                if (!grp->irqinfo[i])
-                       return -ENOMEM;
+                       goto err_out;
+               allocated++;
        }

        grp->regs = of_iomap(np, 0);
        if (!grp->regs)
-               return -ENOMEM;
+               goto err_out;

        gfar_irq(grp, TX)->irq = irq_of_parse_and_map(np, 0);
@@ -522,8 +524,10 @@ static int gfar_parse_group(struct device_node *np,
                gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2);
                if (!gfar_irq(grp, TX)->irq ||
                    !gfar_irq(grp, RX)->irq ||
-                   !gfar_irq(grp, ER)->irq)
-                       return -EINVAL;
+                   !gfar_irq(grp, ER)->irq) {
+                       err = -EINVAL;
+                       goto err_out;
+               }
        }

        grp->priv = priv;
@@ -567,6 +571,13 @@ static int gfar_parse_group(struct device_node *np,
        priv->num_grps++;

        return 0;
+
+err_out:
+       for (i = 0; i < allocated; i++)
+               kfree(grp->irqinfo[i]);
+       if (grp->regs)
+               iounmap(grp->regs);
+       return err;
 }

 /* Reads the controller's registers to determine what interface
--
2.54.0

Attachments

  • smime.p7s [application/pkcs7-signature] 5469 bytes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help