[PATCH 5.15 146/935] sctp: drop a chunk if its transport was removed

From
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date
2026-09-12 18:14:42
Also in
linux-patches
Reply to
Greg Kroah-Hartman, 2026-09-12
5.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hyunwoo Kim <redacted>

commit 03a9d10ecf71f54b2af8020935f2033d4a132be5 upstream.

sctp_rcv() resolves the transport once per packet and leaves it in
chunk->transport. The lookup reference, or the one sctp_add_backlog() takes
if the socket is owned by userspace, keeps it around until the chunk has
been processed.

An authenticated ASCONF DEL-IP can remove it in the meantime.
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. There is a window on both paths: the packet can sit on
the socket backlog, and on the direct path the lookup completes before
bh_lock_sock().

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_inq_push(), next to the existing rcvr->dead check.
Both paths reach it with the association's socket lock held. The peer
retransmits it.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: <redacted>
Signed-off-by: Hyunwoo Kim <redacted>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/aoUJHQmxL0LFIMCw@v4bel (local)
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sctp/inqueue.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -63,8 +63,11 @@ void sctp_inq_free(struct sctp_inq *queu
  */
 void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
 {
-	/* Directly call the packet handling routine. */
-	if (chunk->rcvr->dead) {
+	/* Directly call the packet handling routine.  Drop the chunk if the
+	 * receiver or the transport it was looked up on is gone.
+	 */
+	if (chunk->rcvr->dead ||
+	    (chunk->transport && chunk->transport->dead)) {
 		sctp_chunk_free(chunk);
 		return;
 	}

Thread (970 messages) 970 messages, 11 authors, last reply 2026-09-20
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help