]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sctp: clear control chunk transport if it is being removed
authorXin Long <lucien.xin@gmail.com>
Wed, 5 Aug 2026 15:18:40 +0000 (11:18 -0400)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Aug 2026 16:29:47 +0000 (09:29 -0700)
sctp_make_heartbeat_ack() caches the destination transport in
chunk->transport without taking a reference. When src_out_of_asoc_ok is
enabled, the HEARTBEAT ACK may remain queued on control_chunk_list instead
of being transmitted immediately.

If the peer transport is removed while the chunk is still queued,
sctp_assoc_rm_peer() drops the transport and schedules it for RCU freeing,
but only clears cached transport pointers in out_chunk_list.  The queued
control chunk therefore retains a dangling transport pointer.

Once an ASCONF_ACK clears the suppression and the queued control chunk is
transmitted, SCTP dereferences the stale transport pointer, leading to a
use-after-free.

Fix this by also clearing chunk->transport for queued control chunks in
control_chunk_list when removing the transport.

Fixes: 8a07eb0a50ae ("sctp: Add ASCONF operation on the single-homed host")
Reported-by: Daniele Linguaglossa <danielelinguaglossa@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/7e1168cb722132152a29d47e5eafaeac4a3bf6f3.1785943120.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/sctp/associola.c

index b6ac0966420a1f2e8bcbf14df7f4522d9895173f..5b0ae616e1ff9407090affd1c949ec985cab609a 100644 (file)
@@ -573,6 +573,10 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
                if (ch->transport == peer)
                        ch->transport = NULL;
 
+       list_for_each_entry(ch, &asoc->outqueue.control_chunk_list, list)
+               if (ch->transport == peer)
+                       ch->transport = NULL;
+
        asoc->peer.transport_count--;
 
        sctp_ulpevent_notify_peer_addr_change(peer, SCTP_ADDR_REMOVED, 0);