From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00F2C3FF1AC; Fri, 15 May 2026 15:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778860454; cv=none; b=Q6w2LsAp5+2/Vs6r10maU/3R61JmWKgJ7tpc/rmhaID4S82DJG3YM7VGAKKcTbpH/FydrSlrrFtwTwxMIwqSalWoyYjcfHuY/9C57Jnqu7hnojNU9aQzKgZEX4Ipz4kGVPxGbqpmtUYieJsZVzBllJoko2479H6ooeLX2G8sqlo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778860454; c=relaxed/simple; bh=ulj3O92ko14l1MA7XhhtyFeAyCyWj2xCNEFmNRYPV6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rzWARBvDEhWJq9O63p6Q7ZYnPj2oYuOeyIAyBBHRQ3uqRrps7kh2G+s90EpyiY6CL2L3P9U/FwbaPoW0+1O4ZXTtGRyJlfJEBrr9i5NqFYYPQnFPRjoPDTHwBi9os6fX2swkZIGoN3m46YF/jIhxBZqMyxezVSB2x7Gipc8R7is= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=Oe1taeV4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="Oe1taeV4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A2D1C2BCB0; Fri, 15 May 2026 15:54:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1778860453; bh=ulj3O92ko14l1MA7XhhtyFeAyCyWj2xCNEFmNRYPV6A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Oe1taeV4Xgh20J7lRqKWulY6JU/HC1ndAzSYK7TBvpKIqwm1ojaa9JLeiouIzDSlc jpg9dc+xWZYiQKvM23iFLBtUiV+f7VL8zefhTBPDZt5W/oizBNxV6qtT+KD+MkCkZl gaue//kZsmIifg6/L6Dl0Aa699qVwXYkrrM++2P8= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ben Morris , Xin Long , Jakub Kicinski Subject: [PATCH 6.12 094/144] sctp: revalidate list cursor after sctp_sendmsg_to_asoc() in SCTP_SENDALL Date: Fri, 15 May 2026 17:48:40 +0200 Message-ID: <20260515154655.689753488@linuxfoundation.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260515154653.469907118@linuxfoundation.org> References: <20260515154653.469907118@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ben Morris commit abb5f36771cc4c05899b34000829a787572a8817 upstream. The SCTP_SENDALL path in sctp_sendmsg() iterates ep->asocs with list_for_each_entry_safe(), which caches the next entry in @tmp before the loop body runs. The body calls sctp_sendmsg_to_asoc(), which may drop the socket lock inside sctp_wait_for_sndbuf(). While the lock is dropped, another thread can SCTP_SOCKOPT_PEELOFF the association cached in @tmp, migrating it to a new endpoint via sctp_sock_migrate() (list_del_init() + list_add_tail() to newep->asocs), and optionally close the new socket which frees the association via kfree_rcu(). The cached @tmp can also be freed by a network ABORT for that association, processed in softirq while the lock is dropped. sctp_wait_for_sndbuf() revalidates @asoc (the current entry) on re-lock via the "sk != asoc->base.sk" and "asoc->base.dead" checks, but nothing revalidates @tmp. After a successful return, the iterator advances to the stale @tmp, yielding either a use-after-free (if the peeled socket was closed) or a list-walk onto the new endpoint's list head (type confusion of &newep->asocs as a struct sctp_association *). Both are reachable from CapEff=0; the type-confusion path gives controlled indirect call via the outqueue.sched->init_sid pointer. Fix by re-deriving @tmp from @asoc after sctp_sendmsg_to_asoc() returns. @asoc is known to still be on ep->asocs at that point: the only callers that list_del an association from ep->asocs are sctp_association_free() (which sets asoc->base.dead) and sctp_assoc_migrate() (which changes asoc->base.sk), and sctp_wait_for_sndbuf() checks both under the lock before any successful return; a tripped check propagates as err < 0 and the loop bails before the re-derive. The SCTP_ABORT path in sctp_sendmsg_check_sflags() returns 0 and the loop hits 'continue' before sctp_sendmsg_to_asoc() is ever called, so the @tmp cached by list_for_each_entry_safe() still covers the lock-held free that ba59fb027307 ("sctp: walk the list of asoc safely") was added for. Fixes: 4910280503f3 ("sctp: add support for snd flag SCTP_SENDALL process in sendmsg") Cc: stable@vger.kernel.org Signed-off-by: Ben Morris Acked-by: Xin Long Link: https://patch.msgid.link/20260508001455.3137-1-joycathacker@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/sctp/socket.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1986,6 +1986,15 @@ static int sctp_sendmsg(struct sock *sk, goto out_unlock; iov_iter_revert(&msg->msg_iter, err); + + /* sctp_sendmsg_to_asoc() may have released the socket + * lock (sctp_wait_for_sndbuf), during which other + * associations on ep->asocs could have been peeled + * off or freed. @asoc itself is revalidated by the + * base.dead and base.sk checks in sctp_wait_for_sndbuf, + * so re-derive the cached cursor from it. + */ + tmp = list_next_entry(asoc, asocs); } goto out_unlock;