Re: [PATCH net] sctp: drop a backlogged chunk if its transport was removed
Xin Long <[email protected]>
| Newsgroups | org.kernel.vger.linux-sctp,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CADvbK_e60CFEVUVo25Tkcw_p4y16o8vZCf0N=hH+bUoEqpu6Qg@mail.gmail.com> |
On Fri, Aug 14, 2026 at 7:43 PM Hyunwoo Kim <[email protected]> wrote: > > sctp_rcv() resolves the transport once per packet and leaves it in > chunk->transport. If the socket is owned by userspace the packet goes to > the socket backlog, and sctp_add_backlog() takes a reference on that > transport. > > An authenticated ASCONF DEL-IP in an earlier backlogged packet can remove > it. sctp_assoc_rm_peer() takes the transport out of the association and > calls sctp_transport_free(), which tags it dead and drops the reference > the association held. The backlogged packet still holds a reference, so > the transport stays around. > > The DATA chunk in that packet puts the removed transport back into > asoc->peer.last_data_from. Once the packet is done that reference goes > away and the transport is freed by RCU, so the next delayed SACK carries > the pointer into the SACK chunk and sctp_outq_select_transport() reads the > freed transport's state. > > Drop the chunk in sctp_backlog_rcv(), next to the existing rcvr->dead > check. The peer retransmits it. Guarding the last_data_from assignment is > not enough, sctp_assoc_rm_peer() clears more than that one pointer and > letting the packet run fills them in again. sctp_wait_for_sndbuf() already > uses the dead flag this way on the send side. > > Fixes: df132eff4638 ("sctp: clear the transport of some out_chunk_list chunks in sctp_assoc_rm_peer") > Cc: [email protected] > Signed-off-by: Hyunwoo Kim <[email protected]> > --- > net/sctp/input.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/net/sctp/input.c b/net/sctp/input.c > index 864741fae4187e..83b8361d149251 100644 > --- a/net/sctp/input.c > +++ b/net/sctp/input.c > @@ -285,9 +285,10 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) > > /* If the rcvr is dead then the association or endpoint > * has been deleted and we can safely drop the chunk > - * and refs that we are holding. > + * and refs that we are holding. Same if the transport > + * we looked up has been removed in the meantime. > */ > - if (rcvr->dead) { > + if (rcvr->dead || (t && t->dead)) { > sctp_chunk_free(chunk); > goto done; > } > -- > 2.43.0 > Can you try to move the check to sctp_inq_push() to also cover the case Sashik reported? https://netdev-ai.bots.linux.dev/sashiko/#/patchset/an-oGfEatacPTSX-%40v4bel Thanks.