On February 22, 2024, CVE-2024-26606 was assigned to a significant vulnerability in the Linux kernel binder driver affecting how epoll-based threading is signaled. While the official fix has landed in recent kernel releases, this issue demonstrated a hard-to-diagnose edge case leading to denial of service scenarios.
Below, I'll break down what this bug means, how it can be exploited, and how it was fixed—with code snippets and links for further reading, all in straightforward language.
What Is Linux Binder?
Binder is a special communications system used mainly in Android and sometimes in desktop Linux, too. It lets processes talk to each other in a controlled way. To keep things fast and efficient, binder uses I/O multiplexing systems like epoll so threads can sleep until there’s work for them.
The Vulnerability: Missed Wakeups in epoll Threads
CVE-2024-26606 describes a race condition in the Linux binder driver (drivers/android/binder.c), affecting threads using (e)poll (like epoll_wait()) for work notification.
Core Problem
Here’s what went wrong:
1. A thread submits a command: It uses BINDER_WRITE_READ syscall, sometimes *without* a read buffer.
2. It expects an event: The thread does not check for immediate response, instead calling epoll_wait() to get notified when there’s stuff to handle.
3. No wakeup happens: If the command enqueues work for itself, the kernel fails to fire the wakeup event to the same thread's epoll wait.
4. Thread gets stuck: The thread goes to sleep forever (or until killed), missing its own queued event. Even submitting more commands won’t wake it up, as it has pending work already.
Over time, applications relying on binder + epoll can hang or deadlock, which is especially nasty for system processes in Android.
Exploiting CVE-2024-26606
This bug is not a privilege escalation, but a denial of service: you can use it to make a service or even the whole system hang.
`c
int fd = open("/dev/binder", O_RDWR);
.write_buffer = ...,
.read_size = , // Crucial: No read buffer!
.read_buffer = ,
};
epoll_wait(efd, events, 1, -1);
// Thread sleeps here -- even if an event is ready!
`
If the driver fails to wake this thread (as in the buggy version), the code waits forever. Flooding multiple threads this way can kill service availability.
Patch: How Was It Fixed?
The fix, merged as commit 239d097197a, ensures self-wakeup:
> When a thread queues work to itself, we always call for a poll wakeup so the thread notices the new event—even if the sender is itself.
Relevant fixed code
/* in binder_poll() or similar */
if (thread_has_pending_work(thread)) {
wake_up_interruptible_poll(&thread->wait, POLLIN | POLLRDNORM);
}
Now, even if a thread queues its own work, epoll gets notified—the deadlock vanishes.
References
- CVE-2024-26606 at NVD
- Linux kernel commit (kernel.org)
- Android binder driver docs
Summary
CVE-2024-26606 is a subtle, yet severe, kernel bug affecting how threads using epoll with the binder driver get notified of their own enqueued work. Unpatched, it can freeze binder-based apps or services. Luckily, newer kernels include a simple fix—always wake up epoll threads, even for self-work.
If you build or use custom kernels, update ASAP. This is the kind of bug that's hard to track down with regular debugging tools but can bring down important system services on anything using binder.
Feel free to share this as reference or for practical demonstrations—the vulnerability is subtle, but its effects are real!
Timeline
Published on: 02/26/2024 16:28:00 UTC
Last modified on: 04/17/2024 17:49:01 UTC