CVE-2026-46227

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
28/05/2026
Last modified:
30/05/2026

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> sctp: revalidate list cursor after sctp_sendmsg_to_asoc() in SCTP_SENDALL<br /> <br /> The SCTP_SENDALL path in sctp_sendmsg() iterates ep-&gt;asocs with<br /> list_for_each_entry_safe(), which caches the next entry in @tmp before<br /> the loop body runs. The body calls sctp_sendmsg_to_asoc(), which may<br /> drop the socket lock inside sctp_wait_for_sndbuf().<br /> <br /> While the lock is dropped, another thread can SCTP_SOCKOPT_PEELOFF the<br /> association cached in @tmp, migrating it to a new endpoint via<br /> sctp_sock_migrate() (list_del_init() + list_add_tail() to<br /> newep-&gt;asocs), and optionally close the new socket which frees the<br /> association via kfree_rcu(). The cached @tmp can also be freed by a<br /> network ABORT for that association, processed in softirq while the<br /> lock is dropped.<br /> <br /> sctp_wait_for_sndbuf() revalidates @asoc (the current entry) on re-lock<br /> via the "sk != asoc-&gt;base.sk" and "asoc-&gt;base.dead" checks, but nothing<br /> revalidates @tmp. After a successful return, the iterator advances to<br /> the stale @tmp, yielding either a use-after-free (if the peeled socket<br /> was closed) or a list-walk onto the new endpoint&amp;#39;s list head (type<br /> confusion of &amp;newep-&gt;asocs as a struct sctp_association *).<br /> <br /> Both are reachable from CapEff=0; the type-confusion path gives<br /> controlled indirect call via the outqueue.sched-&gt;init_sid pointer.<br /> <br /> Fix by re-deriving @tmp from @asoc after sctp_sendmsg_to_asoc()<br /> returns. @asoc is known to still be on ep-&gt;asocs at that point: the<br /> only callers that list_del an association from ep-&gt;asocs are<br /> sctp_association_free() (which sets asoc-&gt;base.dead) and<br /> sctp_assoc_migrate() (which changes asoc-&gt;base.sk), and<br /> sctp_wait_for_sndbuf() checks both under the lock before any<br /> successful return; a tripped check propagates as err