[PATCH] pnp: card_probe(): fix memory leak
authorJesper Juhl <jesper.juhl@gmail.com>
Sun, 25 Jun 2006 12:47:17 +0000 (05:47 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 25 Jun 2006 17:01:01 +0000 (10:01 -0700)
We can leak `clink' if drv->probe == 0.

Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
Cc: Adam Belay <ambx1@neo.rr.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/pnp/card.c

index bb19c64073c6ddd8e8544de2c773e846e1235349..0b4adcb60df4060db26bbaef9e6a6c26dc40ff3b 100644 (file)
@@ -60,30 +60,34 @@ static void card_remove_first(struct pnp_dev * dev)
        card_remove(dev);
 }
 
-static int card_probe(struct pnp_card * card, struct pnp_card_driver * drv)
+static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
 {
-       const struct pnp_card_device_id *id = match_card(drv,card);
-       if (id) {
-               struct pnp_card_link * clink = pnp_alloc(sizeof(struct pnp_card_link));
-               if (!clink)
-                       return 0;
-               clink->card = card;
-               clink->driver = drv;
-               clink->pm_state = PMSG_ON;
-               if (drv->probe) {
-                       if (drv->probe(clink, id)>=0)
-                               return 1;
-                       else {
-                               struct pnp_dev * dev;
-                               card_for_each_dev(card, dev) {
-                                       if (dev->card_link == clink)
-                                               pnp_release_card_device(dev);
-                               }
-                               kfree(clink);
-                       }
-               } else
-                       return 1;
+       const struct pnp_card_device_id *id;
+       struct pnp_card_link *clink;
+       struct pnp_dev *dev;
+
+       if (!drv->probe)
+               return 0;
+       id = match_card(drv,card);
+       if (!id)
+               return 0;
+
+       clink = pnp_alloc(sizeof(*clink));
+       if (!clink)
+               return 0;
+       clink->card = card;
+       clink->driver = drv;
+       clink->pm_state = PMSG_ON;
+
+       if (drv->probe(clink, id) >= 0)
+               return 1;
+
+       /* Recovery */
+       card_for_each_dev(card, dev) {
+               if (dev->card_link == clink)
+                       pnp_release_card_device(dev);
        }
+       kfree(clink);
        return 0;
 }