diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 35c69e4911cb082425424e3f5b68c065ba0ef5ab..a92a96f84ef2bd607dd04421d839d8871dd89682 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1983,6 +1983,15 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) goto out_unlock; iov_iter_revert(&msg->msg_iter, err); + + /* sctp_sendmsg_to_asoc() may have released the socket + * lock (sctp_wait_for_sndbuf), during which other + * associations on ep->asocs could have been peeled + * off or freed. @asoc itself is revalidated by the + * base.dead and base.sk checks in sctp_wait_for_sndbuf, + * so re-derive the cached cursor from it. + */ + tmp = list_next_entry(asoc, asocs); } goto out_unlock;