On Fri, Apr 04 2025 at 10:22:38, Xin Long <lucien.xin@xxxxxxxxx> wrote: >> Something like this: >> >> @@ -9225,7 +9227,9 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, >> pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, >> *timeo_p, msg_len); >> >> - /* Increment the association's refcnt. */ >> + /* Increment the transport and association's refcnt. */ >> + if (transport) >> + sctp_transport_hold(transport); >> sctp_association_hold(asoc); >> >> /* Wait on the association specific sndbuf space. */ >> @@ -9252,6 +9256,8 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, >> lock_sock(sk); >> if (sk != asoc->base.sk) >> goto do_error; >> + if (transport && transport->dead) >> + goto do_nonblock; >> >> *timeo_p = current_timeo; >> } >> @@ -9259,7 +9265,9 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, >> out: >> finish_wait(&asoc->wait, &wait); >> >> - /* Release the association's refcnt. */ >> + /* Release the transport and association's refcnt. */ >> + if (transport) >> + sctp_transport_put(transport); >> sctp_association_put(asoc); >> >> return err; >> >> >> So by the time the sending thread re-claims the socket lock it can tell >> whether someone else removed the transport by checking transport->dead >> (set in sctp_transport_free()) and there's a guarantee that the >> transport hasn't been freed yet because we hold a reference to it. >> >> If the whole receive path through sctp_assoc_rm_peer() is protected by >> the same socket lock, as you said, this should be safe. The tests I ran >> seem to work fine. If you're ok with it I'll send another patch to >> supersede this one. >> > LGTM. Good, thanks! I submitted a patch that supersedes this one: https://lore.kernel.org/linux-sctp/20250404-kasan_slab-use-after-free_read_in_sctp_outq_select_transport__20250404-v1-1-5ce4a0b78ef2@xxxxxxxxxx so we can drop this. Cheers, Ricardo