• Eric Dumazet's avatar
    inet: fix possible panic in reqsk_queue_unlink() · b357a364
    Eric Dumazet authored
    [ 3897.923145] BUG: unable to handle kernel NULL pointer dereference at
     0000000000000080
    [ 3897.931025] IP: [<ffffffffa9f27686>] reqsk_timer_handler+0x1a6/0x243
    
    There is a race when reqsk_timer_handler() and tcp_check_req() call
    inet_csk_reqsk_queue_unlink() on the same req at the same time.
    
    Before commit fa76ce73 ("inet: get rid of central tcp/dccp listener
    timer"), listener spinlock was held and race could not happen.
    
    To solve this bug, we change reqsk_queue_unlink() to not assume req
    must be found, and we return a status, to conditionally release a
    refcount on the request sock.
    
    This also means tcp_check_req() in non fastopen case might or not
    consume req refcount, so tcp_v6_hnd_req() & tcp_v4_hnd_req() have
    to properly handle this.
    
    (Same remark for dccp_check_req() and its callers)
    
    inet_csk_reqsk_queue_drop() is now too big to be inlined, as it is
    called 4 times in tcp and 3 times in dccp.
    
    Fixes: fa76ce73 ("inet: get rid of central tcp/dccp listener timer")
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Reported-by: default avatarYuchung Cheng <ycheng@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b357a364
tcp_ipv4.c 61.9 KB