From: Jun Yang <juny24602@gmail.com>
To: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>,
Xin Long <lucien.xin@gmail.com>
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
linux-sctp@vger.kernel.org, netdev@vger.kernel.org,
David Lee <david.lee@trailofbits.com>,
Kyle Zeng <kylebot@openai.com>, Jun Yang <junvyyang@tencent.com>,
stable@kernel.org, TencentOS Corvus AI <corvus@tencent.com>
Subject: [PATCH net v3 2/2] sctp: re-point retained control chunks on association migration
Date: Sat, 26 Sep 2026 18:03:58 +0800 [thread overview]
Message-ID: <20260926100359.78731-3-juny24602@gmail.com> (raw)
In-Reply-To: <20260926100359.78731-1-juny24602@gmail.com>
From: Jun Yang <junvyyang@tencent.com>
sctp_sock_migrate() transfers DATA chunk ownership but leaves retained
control chunks pointing at the old socket. A later retransmission can
therefore access the socket after it has been freed.
Extend the migration walk to cover retained control chunks and use
sctp_control_set_owner_w() to assign their new owner.
Save the old chunk->shkey before setting the new owner and release that
key afterward, since sctp_control_set_owner_w() may select a different
asoc->shkey.
Fixes: d04adf1b3551 ("sctp: reset owner sk for data chunks on out queues when migrating a sock")
Cc: stable@kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Assisted-by: tencentos-corvus-ai:hy4-preview
Signed-off-by: Jun Yang <junvyyang@tencent.com>
---
A KASAN reproducer for this issue is available if requested.
v3:
- Call cb() directly for control chunks.
- Include the shared-key prerequisite as patch 1/2.
v2: https://lore.kernel.org/netdev/20260804113705.45754-1-juny24602@gmail.com/
v1: https://lore.kernel.org/netdev/20260730090537.27629-1-juny24602@gmail.com/
include/net/sctp/sm.h | 1 +
net/sctp/sm_make_chunk.c | 2 +-
net/sctp/socket.c | 37 +++++++++++++++++++++++++++++--------
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 3bfd261a53cc..76605d1ee839 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -252,6 +252,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
struct sctp_fwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
__u16 key_id);
+void sctp_control_set_owner_w(struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc,
__u16 stream_num, __be16 *stream_list,
bool out, bool in);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 84a4c97d0f75..b2eb7568a58e 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -94,7 +94,7 @@ static void sctp_control_release_owner(struct sk_buff *skb)
}
}
-static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
+void sctp_control_set_owner_w(struct sctp_chunk *chunk)
{
struct sctp_association *asoc = chunk->asoc;
struct sk_buff *skb = chunk->skb;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4a08023d52aa..efee9e3e671e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -155,9 +155,15 @@ static void sctp_clear_owner_w(struct sctp_chunk *chunk)
static void sctp_set_owner_w_migrate(struct sctp_chunk *chunk)
{
- sctp_set_owner_w(chunk);
- if (chunk->shkey)
- sctp_auth_shkey_release(chunk->shkey);
+ struct sctp_shared_key *shkey = chunk->shkey;
+
+ if (chunk->msg)
+ sctp_set_owner_w(chunk);
+ else
+ sctp_control_set_owner_w(chunk);
+
+ if (shkey)
+ sctp_auth_shkey_release(shkey);
}
#define traverse_and_process() \
@@ -173,9 +179,9 @@ do { \
prev_msg = msg; \
} while (0)
-static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
- bool clear,
- void (*cb)(struct sctp_chunk *))
+static void sctp_for_each_tx_chunk(struct sctp_association *asoc,
+ bool clear,
+ void (*cb)(struct sctp_chunk *))
{
struct sctp_datamsg *msg, *prev_msg = NULL;
@@ -198,6 +204,21 @@ static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
list_for_each_entry(chunk, &q->out_chunk_list, list)
traverse_and_process();
+
+ list_for_each_entry(chunk, &q->control_chunk_list, list)
+ cb(chunk);
+
+ list_for_each_entry(chunk, &asoc->asconf_ack_list, transmitted_list)
+ cb(chunk);
+
+ list_for_each_entry(chunk, &asoc->addip_chunk_list, list)
+ cb(chunk);
+
+ if (asoc->strreset_chunk)
+ cb(asoc->strreset_chunk);
+
+ if (asoc->addip_last_asconf)
+ cb(asoc->addip_last_asconf);
}
static void sctp_for_each_rx_skb(struct sctp_association *asoc, struct sock *sk,
@@ -9640,9 +9661,9 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
* paths won't try to lock it and then oldsk.
*/
lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
- sctp_for_each_tx_datachunk(assoc, true, sctp_clear_owner_w);
+ sctp_for_each_tx_chunk(assoc, true, sctp_clear_owner_w);
sctp_assoc_migrate(assoc, newsk);
- sctp_for_each_tx_datachunk(assoc, false, sctp_set_owner_w_migrate);
+ sctp_for_each_tx_chunk(assoc, false, sctp_set_owner_w_migrate);
/* If the association on the newsk is already closed before accept()
* is called, set RCV_SHUTDOWN flag.
next prev parent reply other threads:[~2026-09-26 10:04 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-26 10:03 [PATCH net v3 0/2] sctp: re-point retained control chunks on association migration Jun Yang
2026-09-26 10:03 ` [PATCH net v3 1/2] sctp: hold shkey across socket migration Jun Yang
2026-09-30 0:06 ` netdev-bot+sashiko
2026-10-01 1:38 ` Xin Long
2026-09-26 10:03 ` Jun Yang [this message]
2026-09-30 0:06 ` [PATCH net v3 2/2] sctp: re-point retained control chunks on association migration netdev-bot+sashiko
2026-10-01 1:58 ` Xin Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260926100359.78731-3-juny24602@gmail.com \
--to=juny24602@gmail.com \
--cc=corvus@tencent.com \
--cc=davem@davemloft.net \
--cc=david.lee@trailofbits.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=junvyyang@tencent.com \
--cc=kuba@kernel.org \
--cc=kylebot@openai.com \
--cc=linux-sctp@vger.kernel.org \
--cc=lucien.xin@gmail.com \
--cc=marcelo.leitner@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox