CVE-2026-72447: sctp: hold socket lock when dumping endpoints in sctp_diag
In the Linux kernel, the following vulnerability has been resolved:
sctp: hold socket lock when dumping endpoints in sctpdiag
SCTPDIAG endpoint dumping was traversing endpoint address lists without holding locksock(), while those lists could change concurrently via socket operations (e.g., bindx changes). This creates a race where nlareserve() counts addresses under RCU protection, but the subsequent copy may see fewer entries, potentially leaking uninitialized memory to userspace.
Fix this by:
- Taking a reference on each endpoint during hash traversal - Moving socket operations (locksock()) outside readlockbh() - Serializing address list access during dump - Reworking sctpforeachendpoint() to support restart-based traversal with (net, pos) tracking
Also:
- Add WARNONONCE() for inconsistent address counts - Fix idiagstates filtering for LISTEN vs association cases - Skip dumping endpoints being freed (ep->base.dead) - Move dump position tracking into iterator, removing cb->args[4] and its comment for sctpepdump()., - Update the comment for cb->args[4] and remove the comment for unused cb->args[5] for sctpsockdump().
Note: traversal is restart-based and may re-scan buckets multiple times, but this is acceptable due to small bucket sizes and required to support sleeping-safe callbacks.
This issue was reported by Nico Yip (@cyeaa) working with TrendAI Zero Day Initiative.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Rework sctp_for_each_endpoint() to support restart-based traversal, noting that it may re-scan buckets multiple times.
SCTP_DIAG endpoint dumping (sctp_diag) traversal strategy = restart-based traversal - Configuration
Move dump position tracking into the iterator, removing cb->args[4] usage and updating the comment for cb->args[4] while removing the comment for the unused argument.
SCTP_DIAG endpoint dumping iterator state tracking = move dump position tracking into iterator - Configuration
Fix idiag_states filtering for LISTEN vs association cases.
SCTP_DIAG endpoint dumping (LISTEN vs association) idiag_states filtering = fixed - Configuration
Serialize address list access during dump so address lists do not change concurrently while being traversed.
SCTP_DIAG endpoint dumping address list access synchronization = serialize during dump - Configuration
Skip dumping endpoints being freed by checking ep->base.dead (do not dump endpoints that are being freed).
SCTP_DIAG endpoint dumping endpoint lifetime handling = skip dead endpoints - Configuration
Take a reference on each endpoint during hash traversal to prevent concurrent changes while dumping.
SCTP_DIAG endpoint dumping (hash traversal) endpoint reference counting = take reference per endpoint during hash traversal - Configuration
Ensure address counts used for nla_reserve are consistent with subsequent dumping by counting addresses under RCU protection and preventing concurrent socket/address list changes (combined with the locking and serialization fixes).
SCTP_DIAG endpoint address dumping nla reserve/length handling = consistent address counting under RCU - Configuration
Move socket operations (lock_sock()) outside read_lock_bh() to avoid copying fewer entries while lists change concurrently.
SCTP_DIAG endpoint dumping lock_sock placement = outside read_lock_bh() - Configuration
Add WARN_ON_ONCE() for inconsistent address counts during dumping.
SCTP_DIAG endpoint dumping WARN conditions = add WARN_ON_ONCE for inconsistent address counts - Configuration
Maintain required cb->args[5] support for sctp_sock_dump while implementing iterator-based position tracking and restart-based traversal to avoid leaking uninitialized memory.
SCTP_DIAG endpoint dumping (sctp_sock_dump) iterator dump support args = support required cb->args[5] for sctp_sock_dump - Compensating control
Ensure socket locking during SCTP_DIAG endpoint dumping: hold socket lock when dumping endpoints in sctp_diag using sleeping-safe callbacks (i.e., do lock_sock() around the dump’s socket operations rather than only within read_lock_bh()).