• Herbert Xu's avatar
    [DCCP]: Fix sock_orphan dead lock · 134af346
    Herbert Xu authored
    Calling sock_orphan inside bh_lock_sock in dccp_close can lead to dead
    locks.  For example, the inet_diag code holds sk_callback_lock without
    disabling BH.  If an inbound packet arrives during that admittedly tiny
    window, it will cause a dead lock on bh_lock_sock.  Another possible
    path would be through sock_wfree if the network device driver frees the
    tx skb in process context with BH enabled.
    
    We can fix this by moving sock_orphan out of bh_lock_sock.
    
    The tricky bit is to work out when we need to destroy the socket
    ourselves and when it has already been destroyed by someone else.
    
    By moving sock_orphan before the release_sock we can solve this
    problem.  This is because as long as we own the socket lock its
    state cannot change.
    
    So we simply record the socket state before the release_sock
    and then check the state again after we regain the socket lock.
    If the socket state has transitioned to DCCP_CLOSED in the time being,
    we know that the socket has been destroyed.  Otherwise the socket is
    still ours to keep.
    
    This problem was discoverd by Ingo Molnar using his lock validator.
    Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    134af346
proto.c 25.9 KB