• Wei Wang's avatar
    decnet: always not take dst->__refcnt when inserting dst into hash table · f1a0e7d1
    Wei Wang authored
    
    [ Upstream commit 76371d2e ]
    
    In the existing dn_route.c code, dn_route_output_slow() takes
    dst->__refcnt before calling dn_insert_route() while dn_route_input_slow()
    does not take dst->__refcnt before calling dn_insert_route().
    This makes the whole routing code very buggy.
    In dn_dst_check_expire(), dnrt_free() is called when rt expires. This
    makes the routes inserted by dn_route_output_slow() not able to be
    freed as the refcnt is not released.
    In dn_dst_gc(), dnrt_drop() is called to release rt which could
    potentially cause the dst->__refcnt to be dropped to -1.
    In dn_run_flush(), dst_free() is called to release all the dst. Again,
    it makes the dst inserted by dn_route_output_slow() not able to be
    released and also, it does not wait on the rcu and could potentially
    cause crash in the path where other users still refer to this dst.
    
    This patch makes sure both input and output path do not take
    dst->__refcnt before calling dn_insert_route() and also makes sure
    dnrt_free()/dst_free() is called when removing dst from the hash table.
    The only difference between those 2 calls is that dnrt_free() waits on
    the rcu while dst_free() does not.
    Signed-off-by: default avatarWei Wang <weiwan@google.com>
    Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    f1a0e7d1