From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794064941; b=Fg+Mr8yLKK+RlubEx2Q763SjF/1GZvsV3GOrT/hHNtC3hxyGRtJ8Q5UVs99BRe7JXMjz uwjIfqe3HQNXYpPU+oP3aY3JNjFRE9/ThgZToAcx3o9u+e3CqL6RKNKClfzvBxe7EqCsP ahiyvU963Ax6+lfm051E9VHG7LgWaR3mGnLE4JYv2yTIBvms6KQtDbyXUm28Ivfc3T0Cs xyxljsVxHDcNMPLN7r3qYabDvu0SY8X/25kuxnAiQjBrtJv6cNz59DlrhOlQiismXKoX0 /w70J8+knJo+xsRa5uPmLhC1qKKGUhCS1LCm3nteluqSBdmAOYTksG1HdwPpN1TeDrQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794064941; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=rHkLppVNw39KrN7PH2OYqah2NSdph9eV45tdQC6GuNc=; b=zqkT5zFIGSN6pNKK1AJHSADQAaD9r5PEkv85zQ0ykC/adsc/ey4H/xQFkcC2tsOWtSJx f5AvGh1OXkzxc0PsGtWdvaEOq3yIw4SuhUgy7cy5s8392BLP2H1+gOSaUu87dsqnmQ6fX pi0xS64/rzqUkgiwbPLL3ZBtDjMBxiAW8GvrzrPn9i6MP+VqQUmzVk3LBzwNQHhCkk8Mi ZH8BckHrFT8IVW56LK3hNmyCvIqmFfKZ9GS85f4W+fZW9DQNZ5eH2Y+z8v/U51zLQm0dj AzvTDyDy7tq2VOxq0uyL3Kxsoee+og6ZHknedvHPvJBNAgQUbYxa0SrsnUmDjp5/jew== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=LAyCy9nd; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC189606A331; Sat, 7 Nov 2026 15:22:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=LAyCy9nd Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E1531F0089F; Sat, 7 Nov 2026 15:22:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794064940; bh=rHkLppVNw39KrN7PH2OYqah2NSdph9eV45tdQC6GuNc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=LAyCy9nda75NSSuGHmD/gpQ9A7ZCKAP/n17H7BKDc1YAczNlnKZD2PzFGygZ3IoP+ yIKposXOuOG90JjWMavhVisyB2uJI4R0aaZg8CzHKsSA7N2w3adSHpq6bJYOXTi1et AOW8IEtqif6kNKYlVLuAK/m6C/bhprYZ3sMofHzk= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Xin Long , Seung Min Shin , Jakub Kicinski , Sasha Levin Subject: [PATCH 7.3 0829/1257] sctp: hold transport reference across connect wait Date: Sat, 7 Nov 2026 08:52:05 -0500 Message-ID: <20261107135002.230375366@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134939.434104957@linuxfoundation.org> References: <20261107134939.434104957@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Seung Min Shin [ Upstream commit 5bef8649bb9ac4b2a014bcc227202ebd2df824be ] sctp_sendmsg_to_asoc() selects a transport before waiting for a new interleaved association to become established. sctp_wait_for_connect() drops the socket lock while sleeping. While the lock is dropped, backlog processing can handle a COOKIE ACK and an ASCONF DEL-IP that removes the selected transport. sctp_assoc_rm_peer() then marks the transport dead and drops its association-owned reference. The transport can be freed through RCU before the send path resumes. After the wait, the stale pointer is assigned to newly created DATA or I-DATA chunks and later dereferenced by sctp_outq_select_transport(). Hold a reference to the selected transport across sctp_wait_for_connect(). After the socket lock is reacquired, abort the send if the transport was marked dead. Callers without a selected transport pass NULL and retain their existing behavior. Cc: stable@vger.kernel.org Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave") Acked-by: Xin Long Signed-off-by: Seung Min Shin Link: https://patch.msgid.link/20261011162750.1529631-1-guncraft2000@naver.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sctp/socket.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 321898f22d80d..c616f1609d0cf 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -75,7 +75,8 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, struct sctp_transport *transport, long *timeo_p, size_t msg_len); static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p); -static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p); +static int sctp_wait_for_connect(struct sctp_association *, + struct sctp_transport *, long *timeo_p); static int sctp_wait_for_accept(struct sock *sk, long timeo); static void sctp_wait_for_close(struct sock *sk, long timeo); static void sctp_destruct_sock(struct sock *sk); @@ -1245,7 +1246,7 @@ static int __sctp_connect(struct sock *sk, struct sockaddr *kaddrs, *assoc_id = asoc->assoc_id; timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); - return sctp_wait_for_connect(asoc, &timeo); + return sctp_wait_for_connect(asoc, NULL, &timeo); out_free: pr_debug("%s: took out_free path with asoc:%p kaddrs:%p err:%d\n", @@ -1847,7 +1848,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, if (asoc->ep->intl_enable) { timeo = sock_sndtimeo(sk, 0); - err = sctp_wait_for_connect(asoc, &timeo); + err = sctp_wait_for_connect(asoc, transport, &timeo); if (err || sk->sk_shutdown & RCV_SHUTDOWN) { err = -ESRCH; goto err; @@ -1890,7 +1891,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, if (unlikely(wait_connect)) { timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); - sctp_wait_for_connect(asoc, &timeo); + sctp_wait_for_connect(asoc, NULL, &timeo); } err = msg_len; @@ -9390,7 +9391,9 @@ static bool sctp_writeable(const struct sock *sk) /* Wait for an association to go into ESTABLISHED state. If timeout is 0, * returns immediately with EINPROGRESS. */ -static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) +static int sctp_wait_for_connect(struct sctp_association *asoc, + struct sctp_transport *transport, + long *timeo_p) { struct sock *sk = asoc->base.sk; int err = 0; @@ -9399,12 +9402,16 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) pr_debug("%s: asoc:%p, timeo:%ld\n", __func__, asoc, *timeo_p); - /* Increment the association's refcnt. */ + /* Hold references while the socket lock is dropped. */ + if (transport) + sctp_transport_hold(transport); sctp_association_hold(asoc); for (;;) { prepare_to_wait_exclusive(&asoc->wait, &wait, TASK_INTERRUPTIBLE); + if (transport && transport->dead) + goto do_transport_dead; if (!*timeo_p) goto do_nonblock; if (sk->sk_shutdown & RCV_SHUTDOWN) @@ -9433,7 +9440,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) out: finish_wait(&asoc->wait, &wait); - /* Release the association's refcnt. */ + if (transport) + sctp_transport_put(transport); sctp_association_put(asoc); return err; @@ -9452,6 +9460,10 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) do_nonblock: err = -EINPROGRESS; goto out; + +do_transport_dead: + err = -EAGAIN; + goto out; } static int sctp_wait_for_accept(struct sock *sk, long timeo) -- 2.53.0