• Julian Anastasov's avatar
    neigh: do not modify unlinked entries · 914b0ef2
    Julian Anastasov authored
    [ Upstream commit 2c51a97f ]
    
    The lockless lookups can return entry that is unlinked.
    Sometimes they get reference before last neigh_cleanup_and_release,
    sometimes they do not need reference. Later, any
    modification attempts may result in the following problems:
    
    1. entry is not destroyed immediately because neigh_update
    can start the timer for dead entry, eg. on change to NUD_REACHABLE
    state. As result, entry lives for some time but is invisible
    and out of control.
    
    2. __neigh_event_send can run in parallel with neigh_destroy
    while refcnt=0 but if timer is started and expired refcnt can
    reach 0 for second time leading to second neigh_destroy and
    possible crash.
    
    Thanks to Eric Dumazet and Ying Xue for their work and analyze
    on the __neigh_event_send change.
    
    Fixes: 767e97e1 ("neigh: RCU conversion of struct neighbour")
    Fixes: a263b309 ("ipv4: Make neigh lookups directly in output packet path.")
    Fixes: 6fd6ce20 ("ipv6: Do not depend on rt->n in ip6_finish_output2().")
    Cc: Eric Dumazet <eric.dumazet@gmail.com>
    Cc: Ying Xue <ying.xue@windriver.com>
    Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
    Acked-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>
    914b0ef2
neighbour.c 77 KB