Published: June 2021
Exclusively Written for This Article – Simpler Language, Step-by-Step Breakdown
📢 TL;DR
A dangerous use-after-free bug affected the Linux kernel's SCTP networking code, causing kernel panics via improper management of association objects during duplicate cookie handling. This could lead to privilege escalation, denial of service, or kernel compromise on vulnerable systems. This article walks you through the underlying issue, shows code snippets, the possible exploit path, and explains the kernel fix committed upstream.
What is SCTP in Linux, and Why Does It Matter?
SCTP (Stream Control Transmission Protocol) is a transport-layer protocol like TCP or UDP. It's used for applications like telephony signaling and WebRTC. SCTP is less popular but remains critical in various telecoms and real-time data products.
Linux supports SCTP via the kernel sctp module (net/sctp/). Vulnerabilities in this code can have a huge impact because it's possible to trigger code paths remotely with network packets.
Vulnerability Type: Use-After-Free (UAF)
- Location: Linux kernel SCTP (net/sctp), specifically in sctp_sf_do_dupcook_a()
- Impact: Kernel Panic / Crash / Potential code execution (DoS or privilege escalation)
What Triggers the Bug?
When a malicious or buggy client sends duplicate COOKIE-ECHO chunks during SCTP handshake, the kernel code follows this (simplified) path:
The kernel receives "duplicate" or unexpected SCTP handshake packets.
2. It accidentally ties new protocol chunks (COOKIE-ACK, SHUTDOWN) to an SCTP _association_ object (asoc) which soon after gets deleted/freed.
3. Later, the code tries to use a pointer (shutdown_last_sent_to) which now refers to memory that’s been freed, causing a kernel panic or possibly controlled memory corruption.
Kernel Panic Trace Example
general protection fault ... RIP: sctp_ulpevent_notify_peer_addr_change+x4b/x1fa [sctp]
[...]
sctp_assoc_control_transport+x1b9/x210 [sctp]
sctp_do_8_2_transport_strike.isra.16+x15c/x220 [sctp]
sctp_cmd_interpreter.isra.21+x1231/x1a10 [sctp]
sctp_do_sm+xc3/x2a [sctp]
sctp_generate_timeout_event+x81/xf [sctp]
Notice: This is a _use-after-free_ bug. The crash is instigated by accessing freed memory (often, but not always, this can be turned to code execution).
🔎 Code Deep Dive – What Went Wrong?
Here's a simplified commented excerpt that shows the problematic section.
Vulnerable Path (Before Fix)
/* in sctp_sf_do_dupcook_a() */
struct sctp_association *new_asoc, *old_asoc;
struct sctp_chunk *shutdown, *cookie_ack;
// ... (processing logic omitted for brevity)
// Allocates COOKIE-ACK & SHUTDOWN using "new_asoc"
cookie_ack = sctp_make_cookie_ack(new_asoc, ...);
shutdown = sctp_make_shutdown(new_asoc, ...);
// Later, sends them using "old_asoc"
sctp_ulpq_tail_event(&old_asoc->ulpq, cookie_ack);
sctp_ulpq_tail_event(&old_asoc->ulpq, shutdown);
// Also, old_asoc->shutdown_last_sent_to = /* pointer to new_asoc transport */
The COOKIE-ACK and SHUTDOWN chunks are built with new_asoc.
- But the code then sends them with old_asoc, and stores references to a transport from new_asoc into old_asoc's structures!
Exploit Path
An attacker could send SCTP packets in a malformed sequence, causing the kernel to go down this buggy path and eventually access freed memory, leading to a kernel panic or even arbitrary code execution in rare cases.
Solution:
Update the active association object earlier, and always use the valid association to allocate and send protocol chunks.
### Code Patch Reference (kernel commit):
Fixed Path (Relevant Snippet)
// Do the asoc update FIRST!
old_asoc = sctp_assoc_update(...); // Switch to the right asoc early
// Allocate chunks with the CORRECT asoc
cookie_ack = sctp_make_cookie_ack(old_asoc, ...);
shutdown = sctp_make_shutdown(old_asoc, ...);
// Send them, and pointers remain valid since old_asoc owns its transport
sctp_ulpq_tail_event(&old_asoc->ulpq, cookie_ack);
sctp_ulpq_tail_event(&old_asoc->ulpq, shutdown);
This change ensures the pointer to the transport always belongs to the correct, still-valid association object.
Patch Diff (simplified)
- /* allocate chunks with new_asoc (may be freed soon) */
- chunk = sctp_make_cookie_ack(new_asoc, ...);
- ...
- sctp_ulpq_tail_event(&old_asoc->ulpq, chunk);
+ /* update asoc first, allocate with the right one */
+ old_asoc = sctp_assoc_update(...);
+ chunk = sctp_make_cookie_ack(old_asoc, ...);
+ sctp_ulpq_tail_event(&old_asoc->ulpq, chunk);
Upgrade your kernel:
Apply Linux kernel v5.10.42+ or downstream vendor patches after June 2021.
modprobe -r sctp
`
- Restrict SCTP traffic: Use firewall rules to block SCTP where not needed.
---
## 📝 References
- Upstream kernel patch commit
- Kernel bug tracker discussion (lkml.org)
- SCTP protocol RFC
- Wikipedia: Use-after-free
---
## 👨💻 Summary and Takeaway
CVE-2021-46999 is a subtle but severe issue in Linux's SCTP networking stack. With a certain sequence of packets, it becomes possible to crash the kernel or worse. The bug stems from sending protocol messages with associations that don’t own them—breaking object ownership rules in code.
If you manage Linux boxes:
- Patch your kernel ASAP!
- Or, remove/disable SCTP if it's not in use.
> General rule: Never reuse or reference memory that your code doesn’t own anymore—be it in the kernel or userland code!
---
Thanks to Alexander and Jere for bringing the issue to closure.
Stay patched, stay safe!
---
*Exclusively written and simplified for clarity. For deeper details, see the original patch and kernel mailing list thread.*
Timeline
Published on: 02/28/2024 09:15:38 UTC
Last modified on: 01/08/2025 17:36:29 UTC