The Anatomy of a Zero-Click Bluetooth Attack
Bluetooth operates as an always-on service on modern Linux distributions, listening for connections, service advertisements, and low-energy scanning even when the user is not actively pairing devices. This constant availability creates a vast remote attack surface reachable by any transmitter within radio range. A zero-click flaw eliminates the last barrier—user interaction—meaning an attacker can compromise a device without pairing, without a pop-up notification, and often without the device needing to be in discoverable mode. The only prerequisite is that the Bluetooth chipset is powered on and the kernel modules are loaded. In such scenarios, a malformed packet from an unauthenticated, anonymous source can trigger memory corruption deep inside the BlueZ protocol stack, eventually yielding kernel-level remote code execution (RCE). The severity is magnified on Linux devices that run as headless servers, IoT gateways, or embedded controllers where Bluetooth is enabled by default for commissioning or sensor access.
The Linux Bluetooth Stack: BlueZ and the Kernel’s Role
Linux handles Bluetooth through a layered architecture. User-space daemons and libraries (BlueZ) manage device pairing, profiles, and the high‑level host controller interface. The kernel side, however, implements the critical L2CAP (Logical Link Control and Adaptation Protocol) layer, the AVDTP (Audio/Video Distribution Transport Protocol) for streaming, and the HCI (Host Controller Interface) driver for communicating with Bluetooth hardware. Within the kernel, the net/bluetooth/ subsystem parses incoming packets, reassembles L2CAP frames, and dispatches data to profile handlers. Because performance-sensitive operations like audio streaming demand fast packet processing, the kernel often executes parsing and capability negotiation without copying data to user space. This design choice, while efficient, means that any logic error in a protocol handler—such as a missing bounds check on an attacker-supplied length field—can be exploited directly in kernel context, with the highest privilege level (ring 0). The zero‑click nature arises because initial L2CAP connection requests and AVDTP signalling can be sent without prior bonding or authentication, making every device with Bluetooth turned on a potential target.
CVE-2020-24490: Dissecting the Heap Buffer Overflow in A2DP
Among the most impactful zero‑click Linux Bluetooth vulnerabilities is CVE-2020-24490, part of the BleedingTooth family disclosed by Google’s security researchers. The flaw resides in the Advanced Audio Distribution Profile (A2DP) handler inside net/bluetooth/a2mp.c and net/bluetooth/avdtp.c. A2DP enables stereo audio streaming over Bluetooth, and during connection setup, a device can advertise its supported media codec capabilities by sending a GetCapabilities or SetConfiguration command via AVDTP. The kernel function responsible for parsing the vendor‑specific codec capabilities receives the length of the capabilities buffer from the packet itself. A deliberate missing upper bound check allows a length value larger than the actual destination buffer allocated on the kernel heap.
When the kernel copies these capabilities, it overflows the heap buffer, corrupting adjacent kernel objects. Attackers can control the overflow data completely—binary data that masquerades as codec information but contains crafted payloads designed to overwrite function pointers, linked-list metadata, or other critical kernel structures. Because the overflow occurs in a context that runs under the BT kernel thread without additional sandboxing, the exploit immediately executes with kernel privileges. The vulnerability is reachable pre‑authentication: an attacker merely needs to send an AVDTP signalling command while the victim’s Bluetooth adapter is scanning for A2DP sinks or sources, a default state on many systems with PulseAudio or PipeWire integrating Bluetooth audio.
Technical Root Cause: Missing Bounds Check on Media Codec Capabilities
In the flawed code path, the kernel function avdtp_parse_capabilities reads a length field from an incoming AVDTP_CAPABILITIES response and uses it to kmalloc a heap buffer. Immediately after allocation, it calls avdtp_get_capabilities, which copies attacker‑supplied data into the buffer using the same length without verifying that the remaining packet data is at least that large or that the length does not exceed a safe maximum. The absence of a check like if (cap_len > MAX_CAP_LEN) or a cross‑validation against the packet’s total payload size permits a classic heap‑based buffer overflow. Because modern kernel heaps use the SLUB allocator with random freelist and hardening options like KASLR, the precise exploitation technique requires shaping the heap so that a target object (e.g., a tty_struct or shmem_file ops table) is placed adjacent to the overflowing buffer. However, the determinism offered by controlled kernel‑state priming (using multiple Bluetooth connections) makes reliable exploitation feasible, as demonstrated by proof‑of‑concept code that achieves a root shell on affected devices from a laptop 30 meters away.
Exploitation Primer: From Malformed Packet to Kernel Code Execution
Exploiting CVE-2020-24490 demands an in‑depth understanding of the kernel heap allocator and Bluetooth timing. The attacker begins by sniffing the victim’s Bluetooth Device Address (BD_ADDR) through passive scanning—the address is broadcast in advertising packets unless privacy features are enabled. Once the address is known, the attacker initiates a low‑level baseband connection without user notification on the target. Over that connection, an L2CAP channel dedicated to AVDTP is opened. The exploit then sends an AVDTP_DISCOVER command and subsequently a series of AVDTP_GET_CAPABILITIES and AVDTP_SET_CONFIGURATION commands, interleaving them with legitimate-looking audio streaming requests to groom the heap.
Crafting the Payload: L2CAP Signaling and AVDTP Stream Configuration
The malicious payload hides inside a AVDTP_START or AVDTP_SET_CONFIGURATION parameter where the vendor‑specific codec field is identified by a legitimate codec ID (e.g., SBC) but contains a fake length larger than the remaining block. The overflow content overwrites a struct file_operations pointer of an adjacent file object or a timer callback. A common technique overwrites the compat_ioctl pointer of a socket file structure. The attacker crafts the new pointer to redirect control to a ROP (Return‑Oriented‑Programming) chain stored in the heap spray area. The ROP chain first computes the kernel base address by leaking a known offset, defeating KASLR, then calls commit_creds(prepare_kernel_cred(0)) to elevate the Bluetooth kernel thread’s credentials to root, and finally invokes a kernel function to execute a user‑space payload, often a reverse shell or a bind shell.
Bypassing Kernel Protections: KASLR, SMAP, SMEP
Modern x86‑64 and ARM64 kernels enable Supervisor Mode Access Prevention (SMAP) and Supervisor Mode Execution Prevention (SMEP) to stop the kernel from accessing user‑space memory directly or executing code on the stack. Exploit developers bypass SMEP by using ROP gadgets that exist in the kernel’s executable code, entirely within supervisor address space. SMAP is avoided because the ROP chain never reads user‑space buffers; it operates on heap data already in kernel memory. KASLR is defeated by exploiting a secondary information leak or by using the heap overflow to corrupt an seq_operations structure, forcing a kernel pointer to be printed in /proc or a similar file. Once the kernel base is known, the ROP chain can reference absolute addresses. The attacker may finally disable SELinux by setting the enforcing flag via selinux_state overridden through a kernel write gadget.
Affected Devices and the Breadth of the Attack Surface
The CVE-2020-24490 vulnerability and its sibling flaws affect every Linux distribution running kernel versions from 4.8 through 5.9 before patches were applied, which includes Ubuntu, Debian, Fedora, Chrome OS, Android (which uses a common kernel base), and countless IoT platforms running Buildroot or Yocto. Any system that loads the btusb module with Bluetooth hardware enabled is a target. Servers in data centers might rarely have Bluetooth, but laptops, workstations, and edge devices frequently do. Industrial tablets and medical equipment that rely on Bluetooth for peripherals are particularly vulnerable because they are often slow to receive kernel updates. Moreover, the attack does not require the victim to pair with the attacker’s device; the mere presence of a Bluetooth adapter in a listening state—scanning for audio sinks when the user hasn’t disabled the service—is sufficient. This makes the flaw a classic “clickless, user‑interaction‑free” vector.
Real‑world attack scenarios could involve an adversary hiding a rogue Bluetooth transmitter in a public space. The transmitter listens for inquiry responses, identifies vulnerable Linux devices by profiling BD_ADDR manufacturer prefixes and the class of device (CoD), and automatically triggers the heap overflow against all discovered targets. Upon successful exploitation, the attacker gains kernel‑level access and can install a persistent rootkit or exfiltrate confidential data. Because the exploit leaves no immediate trace in user‑space logs—Avahi or Bluetooth daemon logs might show a brief connection attempt—detection is exceptionally difficult without kernel‑level auditing enabled.
Mitigation Strategies and Patching Rhythms
The immediate and most effective mitigation is to install the latest kernel security updates that address CVE-2020-24490. Distributions pushed patches in October 2020, so any system running a kernel later than 5.9.1, 5.8.16, 5.4.72, or 4.19.152 is protected. For devices that cannot be updated, administrators should disable Bluetooth entirely by blacklisting the relevant kernel modules (btusb, bluetooth, btintel) via modprobe.d or removing the hardware. Systemd‑based distributions can mask the bluetooth.service. On embedded systems where Bluetooth is essential, implementing a strict Bluetooth MAC address filter at the firmware level and blocking all unknown incoming AVDTP connections using bpfilter or Netfilter hooks can reduce exposure. However, the only complete defense is patching, because attackers can forge BD_ADDR addresses and manipulate L2CAP channels at the baseband level, by‑passing any user‑space firewall.
Linux kernel developers subsequently hardened the BlueZ stack by moving more parsing into user space with btproxy and by adding extensive kmalloc size checks in capability handling. The Bluetooth SIG also introduced core specification updates that deprecate insecure negotiation flows. Nevertheless, the incident underlines that any kernel code processing untrusted wireless input represents a prime target. As long as the Linux Bluetooth stack remains in‑kernel for performance reasons, vulnerability surface reduction through fuzzing (using tools like syzkaller) and runtime mitigations such as CONFIG_INIT_ON_ALLOC_DEFAULT_ON and heap canaries will be critical. By applying kernel updates promptly and using Bluetooth device identification profiles only when necessary, administrators can drastically reduce the attack surface posed by these underlying zero‑click risks.