ipv6: Fix fib6_dump_table walker leak
authorHerbert Xu <herbert@gondor.apana.org.au>
Wed, 14 Jan 2009 06:17:51 +0000 (22:17 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Jan 2009 06:17:51 +0000 (22:17 -0800)
When a fib6 table dump is prematurely ended, we won't unlink
its walker from the list.  This causes all sorts of grief for
other users of the list later.

Reported-by: Chris Caputo <ccaputo@alt.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6_fib.c

index 29c7c99e69f7611034354319b9e6452f26972635..52ee1dced2ffe2ed28c86e6ef7dd355cfe18ee70 100644 (file)
@@ -298,6 +298,10 @@ static void fib6_dump_end(struct netlink_callback *cb)
        struct fib6_walker_t *w = (void*)cb->args[2];
 
        if (w) {
+               if (cb->args[4]) {
+                       cb->args[4] = 0;
+                       fib6_walker_unlink(w);
+               }
                cb->args[2] = 0;
                kfree(w);
        }
@@ -330,15 +334,12 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
                read_lock_bh(&table->tb6_lock);
                res = fib6_walk_continue(w);
                read_unlock_bh(&table->tb6_lock);
-               if (res != 0) {
-                       if (res < 0)
-                               fib6_walker_unlink(w);
-                       goto end;
+               if (res <= 0) {
+                       fib6_walker_unlink(w);
+                       cb->args[4] = 0;
                }
-               fib6_walker_unlink(w);
-               cb->args[4] = 0;
        }
-end:
+
        return res;
 }