• David Ahern's avatar
    ipv6: Handle missing host route in __ipv6_ifa_notify · 6f8564ed
    David Ahern authored
    [ Upstream commit 2d819d25 ]
    
    Rajendra reported a kernel panic when a link was taken down:
    
        [ 6870.263084] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8
        [ 6870.271856] IP: [<ffffffff8efc5764>] __ipv6_ifa_notify+0x154/0x290
    
        <snip>
    
        [ 6870.570501] Call Trace:
        [ 6870.573238] [<ffffffff8efc58c6>] ? ipv6_ifa_notify+0x26/0x40
        [ 6870.579665] [<ffffffff8efc98ec>] ? addrconf_dad_completed+0x4c/0x2c0
        [ 6870.586869] [<ffffffff8efe70c6>] ? ipv6_dev_mc_inc+0x196/0x260
        [ 6870.593491] [<ffffffff8efc9c6a>] ? addrconf_dad_work+0x10a/0x430
        [ 6870.600305] [<ffffffff8f01ade4>] ? __switch_to_asm+0x34/0x70
        [ 6870.606732] [<ffffffff8ea93a7a>] ? process_one_work+0x18a/0x430
        [ 6870.613449] [<ffffffff8ea93d6d>] ? worker_thread+0x4d/0x490
        [ 6870.619778] [<ffffffff8ea93d20>] ? process_one_work+0x430/0x430
        [ 6870.626495] [<ffffffff8ea99dd9>] ? kthread+0xd9/0xf0
        [ 6870.632145] [<ffffffff8f01ade4>] ? __switch_to_asm+0x34/0x70
        [ 6870.638573] [<ffffffff8ea99d00>] ? kthread_park+0x60/0x60
        [ 6870.644707] [<ffffffff8f01ae77>] ? ret_from_fork+0x57/0x70
        [ 6870.650936] Code: 31 c0 31 d2 41 b9 20 00 08 02 b9 09 00 00 0
    
    addrconf_dad_work is kicked to be scheduled when a device is brought
    up. There is a race between addrcond_dad_work getting scheduled and
    taking the rtnl lock and a process taking the link down (under rtnl).
    The latter removes the host route from the inet6_addr as part of
    addrconf_ifdown which is run for NETDEV_DOWN. The former attempts
    to use the host route in __ipv6_ifa_notify. If the down event removes
    the host route due to the race to the rtnl, then the BUG listed above
    occurs.
    
    Since the DAD sequence can not be aborted, add a check for the missing
    host route in __ipv6_ifa_notify. The only way this should happen is due
    to the previously mentioned race. The host route is created when the
    address is added to an interface; it is only removed on a down event
    where the address is kept. Add a warning if the host route is missing
    AND the device is up; this is a situation that should never happen.
    
    Fixes: f1705ec1 ("net: ipv6: Make address flushing on ifdown optional")
    Reported-by: default avatarRajendra Dendukuri <rajendra.dendukuri@broadcom.com>
    Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    6f8564ed
addrconf.c 165 KB