<feed xmlns='http://www.w3.org/2005/Atom'>
<title>laptop-kernel/net/sctp, branch master</title>
<subtitle>Linux kernel tree for laptop</subtitle>
<id>https://git.zx2c4.com/laptop-kernel/atom/net/sctp?h=master</id>
<link rel='self' href='https://git.zx2c4.com/laptop-kernel/atom/net/sctp?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/'/>
<updated>2026-10-13T08:28:23Z</updated>
<entry>
<title>sctp: revalidate output stream after association connect wait</title>
<updated>2026-10-13T08:28:23Z</updated>
<author>
<name>Daehyeon Ko</name>
<email>4ncienth@gmail.com</email>
</author>
<published>2026-10-07T03:57:39Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=b7ad72414c673ce1fa1f463e807cd4f34f8be9bf'/>
<id>urn:sha1:b7ad72414c673ce1fa1f463e807cd4f34f8be9bf</id>
<content type='text'>
When message interleaving is enabled, the first send waits for association
establishment before building its data chunks.  The wait drops the socket
lock, and handshake processing can reduce the output stream count to the
peer-advertised inbound stream count.  sctp_stream_init() then frees the
extension of every removed stream.

The sender resumes with the stream that it checked before the wait.  If the
peer removed that stream, sctp_outq_tail() later dereferences its NULL
extension.  Fatal-oops policies then panic the host.

KASAN: null-ptr-deref in range [0x38-0x3f]
RIP: sctp_outq_tail+0x49e/0xaa0
Call Trace:
 sctp_primitive_SEND
 sctp_sendmsg_to_asoc
 sctp_sendmsg

A range check alone is insufficient.  Stream reconfiguration can grow the
output count again while the lock is released without recreating extensions
freed by the earlier shrink.  The stream can then be in range while its
extension remains NULL.  The send-buffer wait has the same issue.

Factor the range and extension checks into a helper and repeat both after
each send-path wait that drops the socket lock.  Once the lock is
reacquired, the validation remains stable through data creation and
queueing.

If validation fails after the connect wait, the auto-created association is
already established.  Return ESRCH so the existing caller path keeps it
under state-machine ownership instead of freeing it directly, which would
leave protocol, counter and socket state inconsistent.

Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko &lt;4ncienth@gmail.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20261007035739.3472432-1-4ncienth@gmail.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
<entry>
<title>sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute</title>
<updated>2026-10-07T01:15:13Z</updated>
<author>
<name>Hui Peng</name>
<email>benquike@gmail.com</email>
</author>
<published>2026-09-30T04:46:11Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=538b529509c7ab0d909cb65bb7264edca1788d30'/>
<id>urn:sha1:538b529509c7ab0d909cb65bb7264edca1788d30</id>
<content type='text'>
When an SCTP stream output extension structure (streamoute) has not yet
been allocated, sctp_getsockopt_pr_streamstatus() sets the local stack
variables params.sprstat_abandoned_unsent = 0 and
params.sprstat_abandoned_sent = 0, but then immediately jumps to 'out:',
bypassing copy_to_user(). As a result, when an uninitialized user buffer
is passed to getsockopt(SCTP_PR_STREAM_STATUS), the kernel returns
success (0) without copying the zeroed stats back to user space, leaving
uninitialized data in the user buffer.

Refactor the !streamoute check into an if-else chain so that when
streamoute is NULL, params is zeroed and falls through to copy_to_user(),
copying the zeroed stats to user space and setting retval = 0 once before
returning.

Tested in QEMU against Linux 7.3.0-rc3 using an uninitialized
sctp_prstatus user struct passed to getsockopt(SCTP_PR_STREAM_STATUS) on a
freshly created stream: on the unfixed kernel the user struct contains
uninitialized stack garbage; whereas with this fix applied, getsockopt()
copies zeroed stats into user space and returns 0.

Cc: stable@vger.kernel.org
Reviewed-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Signed-off-by: Hui Peng &lt;benquike@gmail.com&gt;
Fixes: f952be79cebd ("sctp: introduce struct sctp_stream_out_ext")
Link: https://patch.msgid.link/20260930044611.204739-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: check RCV_SHUTDOWN after the sendmsg connect wait</title>
<updated>2026-09-30T23:55:47Z</updated>
<author>
<name>Jun Yang</name>
<email>junvyyang@tencent.com</email>
</author>
<published>2026-09-26T09:55:15Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=4f1da630d13de0370e2f6361f961f1c8b384af1c'/>
<id>urn:sha1:4f1da630d13de0370e2f6361f961f1c8b384af1c</id>
<content type='text'>
sctp_wait_for_connect() drops the socket lock while it sleeps. An
out-of-the-blue ABORT can then be processed from the socket backlog and
unlink the association. If a concurrent shutdown(fd, SHUT_RD) sets
RCV_SHUTDOWN, the waiter breaks with err == 0 before checking
asoc-&gt;base.dead. Its final sctp_association_put() can then free the
association, leaving sctp_sendmsg_to_asoc() to continue with a dangling
pointer.

Check RCV_SHUTDOWN along with the wait error in sctp_sendmsg_to_asoc()
before using the association again. The check only accesses the socket,
so it needs no additional association reference. Return the existing
-ESRCH so that sctp_sendmsg() skips freeing a new association that may
already have been destroyed.

Keep sctp_wait_for_connect() unchanged to preserve its behavior for the
connect() caller.

Fixes: 668c9beb9020 ("sctp: implement assign_number for sctp_stream_interleave")
Cc: stable@vger.kernel.org
Reported-by: TencentOS Corvus AI &lt;corvus@tencent.com&gt;
Signed-off-by: Jun Yang &lt;junvyyang@tencent.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20260926095606.68601-1-juny24602@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: hold asoc or transport before mod_timer() in timer handlers</title>
<updated>2026-09-23T01:36:36Z</updated>
<author>
<name>Xin Long</name>
<email>lucien.xin@gmail.com</email>
</author>
<published>2026-09-21T18:03:45Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=cae23ae3f7887a1cf8a75da38edcebeef695040f'/>
<id>urn:sha1:cae23ae3f7887a1cf8a75da38edcebeef695040f</id>
<content type='text'>
Take the association or transport reference before rearming a timer in the
timer handlers.

The existing code calls mod_timer() before taking the reference needed by
the rearmed timer without holding the sock lock. This creates a race with
timer cleanup: if the timer is deleted after mod_timer() returns but before
the reference is taken, the cleanup path can drop the timer's reference and
destroy the transport or association. The timer handler then takes a
reference on the already freed object and eventually drops it, causing a
refcount underflow.

Hold the object before mod_timer() and drop the reference if mod_timer()
reports that the timer was already pending in timer handlers. Apply the
same ordering to the proto-unreachable path, which can rearm a transport
timer outside the timer handlers without holding the sock lock.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Tangxin Xie &lt;xietangxin@h-partners.com&gt;
Signed-off-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/c31b5e3ee2b7274e804f5eba2f21e2412e7eef7a.1790013825.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: discard the rest of the packet on a stale-cookie error</title>
<updated>2026-09-23T01:31:01Z</updated>
<author>
<name>Aohan Mei</name>
<email>henrymei@tencent.com</email>
</author>
<published>2026-09-21T09:37:04Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=4498467a8af06cfa3d71cb04bd7c4170dec8f449'/>
<id>urn:sha1:4498467a8af06cfa3d71cb04bd7c4170dec8f449</id>
<content type='text'>
When an association is in COOKIE-ECHOED state and the peer sends a
bundled [ERROR(Stale Cookie)][DATA] packet from one of its non-primary
addresses, processing the ERROR chunk takes the non-fatal stale-cookie
retry path sctp_sf_do_5_2_6_stale(), which queues
SCTP_CMD_DEL_NON_PRIMARY while keeping the association alive.
sctp_cmd_del_non_primary() removes every non-primary transport -
including the very transport this packet arrived on, which is still
referenced by the receive lookup and shared by all chunks of the
packet via chunk-&gt;transport.

sctp_assoc_rm_peer() does redirect asoc-&gt;peer.last_data_from away from
the removed transport, but right afterwards the bundled DATA chunk
makes sctp_assoc_bh_rcv() re-register
asoc-&gt;peer.last_data_from = chunk-&gt;transport unconditionally, undoing
the redirection with the just-removed transport.

Once the packet is done, the receive reference is dropped and the
transport is RCU-freed, while the surviving association keeps the
dangling last_data_from.  A later FWD-TSN (or the delayed SACK timer)
makes sctp_gen_sack() dereference it (-&gt;param_flags and friends), and
sctp_make_sack()/sctp_outq_select_transport() may write to the freed
object and link it into the live transport list.  This is a
use-after-free triggerable by any malicious SCTP peer (or a local
unprivileged user acting as one) with no capabilities required:

  BUG: KASAN: slab-use-after-free in sctp_do_sm+0x498a/0x5660
  Read of size 4 at addr ffff88800e1e356c by task poc/115
  Call Trace: sctp_do_sm &lt;- sctp_assoc_bh_rcv &lt;- sctp_inq_push &lt;-
              sctp_rcv &lt;- ip_protocol_deliver_rcu &lt;- ip_rcv
  Allocated: sctp_transport_new &lt;- sctp_assoc_add_peer &lt;-
             sctp_process_init (INIT-ACK processing)
  Freed: kfree &lt;- sctp_transport_destroy_rcu &lt;- rcu_core
         (call_rcu queued by sctp_transport_put at end of sctp_rcv)
  The buggy address is located 364 bytes inside of freed 1024-byte
  region [ffff88800e1e3400, ffff88800e1e3800), cache kmalloc-1k

Note that commit 03a9d10ecf71 ("sctp: drop a chunk if its transport
was removed") only covers the window between the receive lookup and
the chunk processing (e.g. an ASCONF DEL-IP racing the socket backlog);
here the transport is removed *while* the packet is being processed,
by an earlier chunk of the same packet, so the drop in sctp_inq_push()
does not reach this path.  Verified with the bundled [ERROR(Stale
Cookie)][DATA] + FWD-TSN reproducer: the KASAN report above still
fires with that commit applied, and is gone with this patch on top.

Fix it by discarding the rest of the packet on this path, as suggested
by Xin.  After the stale-cookie ERROR has sent the association back to
COOKIE-WAIT and removed the non-primary transports, the remaining
chunks of the packet can only run against the restarted handshake
while referencing the removed arrival transport through
chunk-&gt;transport: besides the last_data_from registration above,
sctp_cmd_setup_t2() and the sctp_make_*() reply builders would also
copy that pointer into association-lifetime state that
sctp_assoc_rm_peer() has already sanitized.  Let the peer retransmit
them, in line with what sctp_inq_push() does for chunks whose
transport was removed before processing.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Suggested-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Reported-by: TencentOS Corvus AI &lt;corvus@tencent.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Aohan Mei &lt;henrymei@tencent.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20260921093707.1432184-1-ljp1205831794@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: avoid livelock while updating retransmit path</title>
<updated>2026-09-19T00:24:10Z</updated>
<author>
<name>Yiqi Sun</name>
<email>sunyiqixm@gmail.com</email>
</author>
<published>2026-09-15T09:50:17Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=d2c31b837406395e576afeb25958c98e9938f3f6'/>
<id>urn:sha1:d2c31b837406395e576afeb25958c98e9938f3f6</id>
<content type='text'>
sctp_assoc_update_retran_path() can loop forever when every remaining
transport, including retran_path, is SCTP_UNCONFIRMED: the state check
runs before the wraparound test, so the loop cannot observe that it has
completed a full pass.

Fix this by considering a transport only when it is not UNCONFIRMED,
then checking whether the walk has returned to retran_path. This makes
the full-pass termination independent of the transport state while
preserving the existing fallback selection semantics.

Also restore the NULL guard around the retran_path assignment. In the
all-UNCONFIRMED case there is no eligible replacement transport, and
installing NULL would leave later retransmit-path users and the debug
print with a NULL path.

Fixes: 4c47af4d5eb2 ("net: sctp: rework multihoming retransmission path selection to rfc4960")
Signed-off-by: Yiqi Sun &lt;sunyiqixm@gmail.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20260915095017.942213-1-sunyiqixm@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: validate chunk length in the inqueue parser</title>
<updated>2026-08-30T21:17:53Z</updated>
<author>
<name>Charles Vosburgh</name>
<email>theminershive@gmail.com</email>
</author>
<published>2026-08-27T21:32:53Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=6cfc1b90cb86f4aabc69fb8e30128e07e2cdfa3a'/>
<id>urn:sha1:6cfc1b90cb86f4aabc69fb8e30128e07e2cdfa3a</id>
<content type='text'>
SCTP chunks always include a four-byte generic header, but
sctp_inq_pop() currently accepts shorter declared lengths. A zero-length
chunk leaves chunk_end at the current header.

When ASCONF is covered by the association's SCTP-AUTH policy,
sctp_assoc_bh_rcv() can continue before the state machine performs its
normal chunk-length check. sctp_inq_pop() then returns the same malformed
chunk repeatedly and the receive softirq can lock up.

A remote SCTP peer can trigger this after establishing an association on
a kernel built with CONFIG_IP_SCTP and configured with
net.sctp.addip_enable=1 and net.sctp.auth_enable=1. The reproducer did
not require application credentials, a shared SCTP AUTH key, or
net.sctp.addip_noauth_enable=1.

On commit f967455fb2a5 ("seg6: reset IP6CB after IPv6 decapsulation"),
one zero-length ASCONF caused repeated
watchdog soft-lockup reports in a two-vCPU KVM guest. All 3 pre-trigger
health probes succeeded, while 36 of 37 post-trigger probes failed. With
this change, all 37 post-trigger probes succeeded and no equivalent
soft-lockup signature appeared.

Reject chunks shorter than the generic SCTP header at the shared inqueue
parser boundary. Mark the packet for discard before either caller can
continue processing it, while preserving the four-byte generic minimum.
Declared-length 1 through 4 controls and kernel-generated ASCONF traffic
remained healthy. The patched sctp_hello selftest passed for IPv4 and
IPv6.

The complete private reproducer and validation evidence are available
directly to maintainers on request.

Fixes: bbd0d59809f9 ("[SCTP]: Implement the receive and verification of AUTH chunk")
Cc: stable@vger.kernel.org
Signed-off-by: Charles Vosburgh &lt;theminershive@gmail.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20260827-sctp-zero-chunk-inqueue-v2-1-2e7669c6a6cb@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration</title>
<updated>2026-08-30T21:14:09Z</updated>
<author>
<name>Henry Martin</name>
<email>bsdhenrymartin@gmail.com</email>
</author>
<published>2026-08-28T04:24:25Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=2cb0b0b1ed69430bf73740377ea0a1c44c50db63'/>
<id>urn:sha1:2cb0b0b1ed69430bf73740377ea0a1c44c50db63</id>
<content type='text'>
sctp_verify_asconf() walks ASCONF-ACK parameters with
sctp_walk_params(), which advances by SCTP_PAD4(length), while the
consumer sctp_get_asconf_response() iterates the same parameters
advancing by the raw length, without padding. A single odd-length
parameter desynchronises the two walks and makes the consumer
interpret attacker-controlled bytes at a misaligned offset.

When those bytes yield a length of zero, the while loop over
asconf_ack_len makes no progress, spinning forever in softirq
context, and the watchdog reports a soft lockup. All reads stay
within the received skb, so the lockup is a pure remote denial of
service. A remote peer can trigger it with a crafted ASCONF-ACK on
an ADD-IP enabled association with an outstanding ASCONF (RFC 5061
section 4.1.2 requires the chunk to be authenticated, but the
predefined empty key id 0 allows the peer to compute the same
association HMAC from publicly exchanged parameters, so the gate
does not help).

The SCTP_PARAM_ERR_CAUSE case of sctp_verify_asconf() also performs
no length check, letting a parameter without a complete error
header reach the consumer, which reads errhdr.cause past the end of
the parameter, an out-of-bounds read.

Reject SCTP_PARAM_ERR_CAUSE parameters shorter than
sizeof(struct sctp_addip_param) + sizeof(struct sctp_errhdr) at the
verifier, and advance the consumer iterator with the same padding
rule as the verifier to keep the two walks in lockstep. The verifier
change guarantees a complete error header in every ERR_CAUSE
parameter the consumer can see, so the consumer's asconf_ack_len
check is dropped and it returns err_param-&gt;cause directly. The
consumer padding fix is still required because odd lengths remain
valid for SCTP_PARAM_ERR_CAUSE per RFC 5061.

The issue was found by ZeroHive, a vulnerability hunting agent at
Tencent Yunding Lab.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Henry Martin &lt;bsdhenrymartin@gmail.com&gt;
Acked-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/20260828042431.3873725-1-bsdhenrymartin@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START</title>
<updated>2026-08-28T23:09:25Z</updated>
<author>
<name>Xin Long</name>
<email>lucien.xin@gmail.com</email>
</author>
<published>2026-08-26T19:49:04Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=2188569e7e1b0bc3f3b557dc97ab7a02befc11c8'/>
<id>urn:sha1:2188569e7e1b0bc3f3b557dc97ab7a02befc11c8</id>
<content type='text'>
The SCTP_CMD_TIMER_START handler checks timer_pending() before calling
timer_reduce(). The timer can expire and detach between these operations,
causing timer_reduce() to rearm the timer without taking the association
reference required for the newly armed timer.

The timer callback later unconditionally drops its association reference,
which can leave the association reference count unbalanced and result in
use-after-free during association teardown.

Use the return value of timer_reduce() to determine whether the timer was
actually armed. Take the association reference only when timer_reduce()
successfully starts a new timer, closing the race between checking the
timer state and rearming it.

This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero
Day Initiative.

Fixes: 20a785aa52c8 ("sctp: Don't add the shutdown timer if its already been added")
Reported-by: Zero Day Initiative &lt;zdi-disclosures@trendmicro.com&gt;
Signed-off-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Link: https://patch.msgid.link/9d8f1b5c50329d5ea7c642128d35681abaa9ed20.1787773744.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>sctp: fix stream-&gt;outcnt underflow on duplicate RECONF responses</title>
<updated>2026-08-25T11:33:08Z</updated>
<author>
<name>Jun Yang</name>
<email>junvyyang@tencent.com</email>
</author>
<published>2026-08-24T08:18:20Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/laptop-kernel/commit/?id=3faf13aff243ca9f78d08b1a2956ef5a6fc77b6e'/>
<id>urn:sha1:3faf13aff243ca9f78d08b1a2956ef5a6fc77b6e</id>
<content type='text'>
A cached RECONF chunk may contain more than one request parameter.  A
duplicate response can therefore find and process the same ADD_OUT request
again while another parameter is still outstanding, rolling back outcnt
twice and possibly underflowing it.

Track outstanding request types as bits and clear each bit after its first
response.  Later responses for the same request are then ignored.

Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter")
Cc: stable@kernel.org
Reported-by: TencentOS Corvus AI &lt;corvus@tencent.com&gt;
Link: https://lore.kernel.org/netdev/20260730110225.37371-1-juny24602@gmail.com/
Suggested-by: Xin Long &lt;lucien.xin@gmail.com&gt;
Assisted-by: tencentos-corvus-ai:kimi-k3
Signed-off-by: Jun Yang &lt;junvyyang@tencent.com&gt;
Link: https://patch.msgid.link/20260824081832.98717-3-juny24602@gmail.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
</feed>
