ipv6: fix race between ipv6_del_addr and DAD timer
Subsystems (3)
PATCH 1/1 ipv6: fix race between ipv6_del_addr and DAD timer
From: Andrey Vagin <[email protected]>
Consider the following scenario:
ipv6_del_addr(ifp)
ipv6_ifa_notify(RTM_DELADDR, ifp)
ip6_del_rt(ifp->rt)
after returning from the ipv6_ifa_notify and enabling BH-s back, but *before* calling the addrconf_del_timer the ifp->timer fires and:
addrconf_dad_timer(ifp)
addrconf_dad_completed(ifp)
ipv6_ifa_notify(RTM_NEWADDR, ifp)
ip6_ins_rt(ifp->rt)then return back to the ipv6_del_addr and:
in6_ifa_put(ifp)
inet6_ifa_finish_destroy(ifp)
dst_release(&ifp->rt->u.dst)
After this we have an ifp->rt inserted into fib6 lists, but queued for gc, which in turn can result in oopses in the fib6_run_gc. Maybe some other nasty things, but we caught only the oops in gc so far.
The solution is to disarm the ifp->timer before flushing the rt from it.
---
net/ipv6/addrconf.c +2 -2
@@ -749,12 +749,12 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) }write_unlock_bh (&idev->lock); +addrconf_del_timer (ifp); +ipv6_ifa_notify (RTM_DELADDR , ifp);atomic_notifier_call_chain (&inet6addr_chain,NETDEV_DOWN , ifp); -addrconf_del_timer (ifp); -/* * Purge or update corresponding prefix *
From: Pavel Emelyanov <[email protected]>
Date: Tue, 08 Jul 2008 12:55:24 +0400
Quoted 26 lines
Consider the following scenario:
ipv6_del_addr(ifp)
ipv6_ifa_notify(RTM_DELADDR, ifp)ip6_del_rt(ifp->rt)after returning from the
ipv6_ifa_notifyand enabling BH-s back, but *before* calling theaddrconf_del_timertheifp->timerfires and:
addrconf_dad_timer(ifp)
addrconf_dad_completed(ifp)ipv6_ifa_notify(RTM_NEWADDR, ifp) ip6_ins_rt(ifp->rt)then return back to the
ipv6_del_addrand:
in6_ifa_put(ifp)
inet6_ifa_finish_destroy(ifp)dst_release(&ifp->rt->u.dst)After this we have an
ifp->rtinserted into fib6 lists, but queued for gc, which in turn can result in oopses in thefib6_run_gc. Maybe some other nasty things, but we caught only the oops in gc so far.
Quoted 5 lines
The solution is to disarm the
ifp->timerbefore flushing the rt from it.Signed-off-by Andrey Vagin <[email protected]>Signed-off-by Pavel Emelyanov <[email protected]>
Applied to net-2.6, thanks a lot for this bug fix!