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_c4V6cWiS=fTfCeS602bazwXy0mYCXnF6=eYH08PaRznQ@mail.gmail.com> |
On Mon, Aug 17, 2026 at 1:48 PM Xin Long <[email protected]> wrote: > > 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") Please also double check the 'Fixes' tag, commit df132eff4638 doesn't seem to cause the issue. Thanks. > > 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.