• Eric Dumazet's avatar
    tcp: fix a potential deadlock in tcp_get_info() · d654976c
    Eric Dumazet authored
    Taking socket spinlock in tcp_get_info() can deadlock, as
    inet_diag_dump_icsk() holds the &hashinfo->ehash_locks[i],
    while packet processing can use the reverse locking order.
    
    We could avoid this locking for TCP_LISTEN states, but lockdep would
    certainly get confused as all TCP sockets share same lockdep classes.
    
    [  523.722504] ======================================================
    [  523.728706] [ INFO: possible circular locking dependency detected ]
    [  523.734990] 4.1.0-dbg-DEV #1676 Not tainted
    [  523.739202] -------------------------------------------------------
    [  523.745474] ss/18032 is trying to acquire lock:
    [  523.750002]  (slock-AF_INET){+.-...}, at: [<ffffffff81669d44>] tcp_get_info+0x2c4/0x360
    [  523.758129]
    [  523.758129] but task is already holding lock:
    [  523.763968]  (&(&hashinfo->ehash_locks[i])->rlock){+.-...}, at: [<ffffffff816bcb75>] inet_diag_dump_icsk+0x1d5/0x6c0
    [  523.774661]
    [  523.774661] which lock already depends on the new lock.
    [  523.774661]
    [  523.782850]
    [  523.782850] the existing dependency chain (in reverse order) is:
    [  523.790326]
    -> #1 (&(&hashinfo->ehash_locks[i])->rlock){+.-...}:
    [  523.796599]        [<ffffffff811126bb>] lock_acquire+0xbb/0x270
    [  523.802565]        [<ffffffff816f5868>] _raw_spin_lock+0x38/0x50
    [  523.808628]        [<ffffffff81665af8>] __inet_hash_nolisten+0x78/0x110
    [  523.815273]        [<ffffffff816819db>] tcp_v4_syn_recv_sock+0x24b/0x350
    [  523.822067]        [<ffffffff81684d41>] tcp_check_req+0x3c1/0x500
    [  523.828199]        [<ffffffff81682d09>] tcp_v4_do_rcv+0x239/0x3d0
    [  523.834331]        [<ffffffff816842fe>] tcp_v4_rcv+0xa8e/0xc10
    [  523.840202]        [<ffffffff81658fa3>] ip_local_deliver_finish+0x133/0x3e0
    [  523.847214]        [<ffffffff81659a9a>] ip_local_deliver+0xaa/0xc0
    [  523.853440]        [<ffffffff816593b8>] ip_rcv_finish+0x168/0x5c0
    [  523.859624]        [<ffffffff81659db7>] ip_rcv+0x307/0x420
    
    Lets use u64_sync infrastructure instead. As a bonus, 64bit
    arches get optimized, as these are nop for them.
    
    Fixes: 0df48c26 ("tcp: add tcpi_bytes_acked to tcp_info")
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d654976c
tcp_input.c 176 KB