• Sowmini Varadhan's avatar
    rds: tcp: Sequence teardown of listen and acceptor sockets to avoid races · b21dd450
    Sowmini Varadhan authored
    Commit a93d01f5 ("RDS: TCP: avoid bad page reference in
    rds_tcp_listen_data_ready") added the function
    rds_tcp_listen_sock_def_readable()  to handle the case when a
    partially set-up acceptor socket drops into rds_tcp_listen_data_ready().
    However, if the listen socket (rtn->rds_tcp_listen_sock) is itself going
    through a tear-down via rds_tcp_listen_stop(), the (*ready)() will be
    null and we would hit a panic  of the form
      BUG: unable to handle kernel NULL pointer dereference at   (null)
      IP:           (null)
       :
      ? rds_tcp_listen_data_ready+0x59/0xb0 [rds_tcp]
      tcp_data_queue+0x39d/0x5b0
      tcp_rcv_established+0x2e5/0x660
      tcp_v4_do_rcv+0x122/0x220
      tcp_v4_rcv+0x8b7/0x980
        :
    In the above case, it is not fatal to encounter a NULL value for
    ready- we should just drop the packet and let the flush of the
    acceptor thread finish gracefully.
    
    In general, the tear-down sequence for listen() and accept() socket
    that is ensured by this commit is:
         rtn->rds_tcp_listen_sock = NULL; /* prevent any new accepts */
         In rds_tcp_listen_stop():
             serialize with, and prevent, further callbacks using lock_sock()
             flush rds_wq
             flush acceptor workq
             sock_release(listen socket)
    Signed-off-by: default avatarSowmini Varadhan <sowmini.varadhan@oracle.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    b21dd450
tcp.c 19 KB