]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sctp: fix race between sctp_wait_for_connect and peeloff
authorZhenghang Xiao <kipreyyy@gmail.com>
Wed, 27 May 2026 03:24:11 +0000 (11:24 +0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 28 May 2026 23:36:08 +0000 (16:36 -0700)
sctp_wait_for_connect() drops and re-acquires the socket lock while
waiting for the association to reach ESTABLISHED state. During this
window, another thread can peeloff the association to a new socket via
getsockopt(SCTP_SOCKOPT_PEELOFF), changing asoc->base.sk. After
re-acquiring the old socket lock, sctp_wait_for_connect() returns
success without noticing the migration — the caller then accesses
the association under the wrong lock in sctp_datamsg_from_user().

Add the same sk != asoc->base.sk check that sctp_wait_for_sndbuf()
already has, returning an error if the association was migrated while
we slept.

Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260527032411.60959-1-kipreyyy@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/sctp/socket.c

index 1d2568bb6bc277767ce7637d2b45accd2c9f8f2b..66e12fb0c646adc73ce252f1ace2b1f9ffc55ed9 100644 (file)
@@ -9403,6 +9403,8 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
                release_sock(sk);
                current_timeo = schedule_timeout(current_timeo);
                lock_sock(sk);
+               if (sk != asoc->base.sk)
+                       goto do_error;
 
                *timeo_p = current_timeo;
        }