• Xin Long's avatar
    sctp: not free the new asoc when sctp_wait_for_connect returns err · c863850c
    Xin Long authored
    When sctp_wait_for_connect is called to wait for connect ready
    for sp->strm_interleave in sctp_sendmsg_to_asoc, a panic could
    be triggered if cpu is scheduled out and the new asoc is freed
    elsewhere, as it will return err and later the asoc gets freed
    again in sctp_sendmsg.
    
    [  285.840764] list_del corruption, ffff9f0f7b284078->next is LIST_POISON1 (dead000000000100)
    [  285.843590] WARNING: CPU: 1 PID: 8861 at lib/list_debug.c:47 __list_del_entry_valid+0x50/0xa0
    [  285.846193] Kernel panic - not syncing: panic_on_warn set ...
    [  285.846193]
    [  285.848206] CPU: 1 PID: 8861 Comm: sctp_ndata Kdump: loaded Not tainted 4.19.0-rc7.label #584
    [  285.850559] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
    [  285.852164] Call Trace:
    ...
    [  285.872210]  ? __list_del_entry_valid+0x50/0xa0
    [  285.872894]  sctp_association_free+0x42/0x2d0 [sctp]
    [  285.873612]  sctp_sendmsg+0x5a4/0x6b0 [sctp]
    [  285.874236]  sock_sendmsg+0x30/0x40
    [  285.874741]  ___sys_sendmsg+0x27a/0x290
    [  285.875304]  ? __switch_to_asm+0x34/0x70
    [  285.875872]  ? __switch_to_asm+0x40/0x70
    [  285.876438]  ? ptep_set_access_flags+0x2a/0x30
    [  285.877083]  ? do_wp_page+0x151/0x540
    [  285.877614]  __sys_sendmsg+0x58/0xa0
    [  285.878138]  do_syscall_64+0x55/0x180
    [  285.878669]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    This is a similar issue with the one fixed in Commit ca3af4dd
    ("sctp: do not free asoc when it is already dead in sctp_sendmsg").
    But this one can't be fixed by returning -ESRCH for the dead asoc
    in sctp_wait_for_connect, as it will break sctp_connect's return
    value to users.
    
    This patch is to simply set err to -ESRCH before it returns to
    sctp_sendmsg when any err is returned by sctp_wait_for_connect
    for sp->strm_interleave, so that no asoc would be freed due to
    this.
    
    When users see this error, they will know the packet hasn't been
    sent. And it also makes sense to not free asoc because waiting
    connect fails, like the second call for sctp_wait_for_connect in
    sctp_sendmsg_to_asoc.
    
    Fixes: 668c9beb ("sctp: implement assign_number for sctp_stream_interleave")
    Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
    Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    c863850c
socket.c 247 KB