Skip to content

Commit

Permalink
[IPV6]: Don't hold extra ref count in ipv6_ifa_notify
Browse files Browse the repository at this point in the history
Currently the logic in ipv6_ifa_notify is to hold an extra reference
count for addrconf dst's that get added to the routing table.  Thus,
when addrconf dst entries are taken out of the routing table, we need
to drop that dst.  However, addrconf dst entries may be removed from
the routing table by means other than __ipv6_ifa_notify.

So we're faced with the choice of either fixing up all places where
addrconf dst entries are removed, or dropping the extra reference count
altogether.

I chose the latter because the ifp itself always holds a dst reference
count of 1 while it's alive.  This is dropped just before we kfree the
ifp object.  Therefore we know that in __ipv6_ifa_notify we will always
hold that count.

This bug was found by Eric W. Biederman.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed Feb 3, 2006
1 parent 42c5e15 commit 4641e7a
Showing 1 changed file with 1 addition and 5 deletions.
6 changes: 1 addition & 5 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3321,9 +3321,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)

switch (event) {
case RTM_NEWADDR:
dst_hold(&ifp->rt->u.dst);
if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
dst_release(&ifp->rt->u.dst);
ip6_ins_rt(ifp->rt, NULL, NULL, NULL);
if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp);
break;
Expand All @@ -3334,8 +3332,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
dst_hold(&ifp->rt->u.dst);
if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
dst_free(&ifp->rt->u.dst);
else
dst_release(&ifp->rt->u.dst);
break;
}
}
Expand Down

0 comments on commit 4641e7a

Please sign in to comment.