• Xin Long's avatar
    tipc: fix a null-ptr-deref in tipc_topsrv_accept · 82cb4e46
    Xin Long authored
    syzbot found a crash in tipc_topsrv_accept:
    
      KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
      Workqueue: tipc_rcv tipc_topsrv_accept
      RIP: 0010:kernel_accept+0x22d/0x350 net/socket.c:3487
      Call Trace:
       <TASK>
       tipc_topsrv_accept+0x197/0x280 net/tipc/topsrv.c:460
       process_one_work+0x991/0x1610 kernel/workqueue.c:2289
       worker_thread+0x665/0x1080 kernel/workqueue.c:2436
       kthread+0x2e4/0x3a0 kernel/kthread.c:376
       ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306
    
    It was caused by srv->listener that might be set to null by
    tipc_topsrv_stop() in net .exit whereas it's still used in
    tipc_topsrv_accept() worker.
    
    srv->listener is protected by srv->idr_lock in tipc_topsrv_stop(), so add
    a check for srv->listener under srv->idr_lock in tipc_topsrv_accept() to
    avoid the null-ptr-deref. To ensure the lsock is not released during the
    tipc_topsrv_accept(), move sock_release() after tipc_topsrv_work_stop()
    where it's waiting until the tipc_topsrv_accept worker to be done.
    
    Note that sk_callback_lock is used to protect sk->sk_user_data instead of
    srv->listener, and it should check srv in tipc_topsrv_listener_data_ready()
    instead. This also ensures that no more tipc_topsrv_accept worker will be
    started after tipc_conn_close() is called in tipc_topsrv_stop() where it
    sets sk->sk_user_data to null.
    
    Fixes: 0ef897be ("tipc: separate topology server listener socket from subcsriber sockets")
    Reported-by: syzbot+c5ce866a8d30f4be0651@syzkaller.appspotmail.com
    Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
    Acked-by: default avatarJon Maloy <jmaloy@redhat.com>
    Link: https://lore.kernel.org/r/4eee264380c409c61c6451af1059b7fb271a7e7b.1666120790.git.lucien.xin@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    82cb4e46
topsrv.c 18.4 KB