CVE-2025-21846 - Linux Kernel acct(2) NULL Pointer Dereference Vulnerability Explained
A new Linux kernel vulnerability, CVE-2025-21846, was recently identified and resolved. The bug existed in the implementation of the acct(2) system call—a legacy process accounting interface. If exploited, this flaw could cause a kernel crash (NULL pointer dereference) under specific conditions. This post explains what happened, who might be affected, how the issue was patched, and provides code examples and links for further reading.
What Is acct(2)?
The acct(2) system call lets you enable or disable process accounting on a file. For example, when you run:
acct("/var/account/pacct");
the kernel will log information about every process that terminates. It's mostly a feature for servers or specialized environments, and not widely used in daily Linux desktops.
The Vulnerability: How The Crash Happens
The vulnerability was reported in https://lkml.org/lkml/2024/5/30/123 and involves a specific use-case:
- A program calls acct(2) and points it at a special sysfs file—specifically, /sys/power/resume.
When a process exits, Linux tries to write accounting information to that file.
- At this point, the process's file system context (current->fs) has already been destroyed because the process is about to disappear.
Accessing this context then triggers a NULL pointer dereference (kernel crash!).
This can be abused by unprivileged users on some systems to crash the kernel, causing a denial of service.
If you have sufficient privileges, something as simple as this could hit the crash
# Only root can do this
acct /sys/power/resume
Then cause a process to exit—kernel panic may follow.
Exploit Scenario
While not trivially exploitable as "code execution," a local user with the ability to call acct(2) (usually root) could intentionally crash the system by pointing it at a sysfs file, such as /sys/power/resume.
A possible proof-of-concept (POC)
#include <unistd.h>
#include <sys/acct.h>
#include <stdio.h>
int main() {
// Requires root privileges
if (acct("/sys/power/resume") != ) {
perror("acct");
return 1;
}
// Exiting process triggers the bug
return ;
}
Running this program (as root) could crash the kernel on vulnerable versions.
Root Cause: Exit and current->fs
The actual technical cause is that the kernel accounting code tried to access current->fs after the process had called exit_fs(). At this stage, current->fs is NULL, so any access results in a kernel panic due to a NULL pointer dereference.
Original Vulnerable Code Snippet (Simplified)
void do_acct_process_exit() {
if (acctp) {
// This can cause kernel crash if current->fs is NULL
file = filp_open(acctp, ...);
vfs_write(file, ...); // Danger: fs context may not exist!
}
}
The Fix: Moving Writes to the Workqueue
Developers fixed the bug by moving the actual write to a kernel workqueue that runs after the process exits, but crucially, with the permissions and context of the original process. This prevents access to a destroyed current->fs.
Fixed Logic (Pseudo-code)
void do_acct_process_exit() {
if (acctp) {
// Queue the write instead of doing it directly
queue_work(acct_write_workqueue, &acct_work_item);
}
}
void acct_write_work_item() {
// Run this in a safe context with the caller's credentials
// Do the file write here instead
}
Impact: No user-facing changes, but the kernel can no longer be crashed this way.
Why This Interface Is Problematic
Even with the fix, developers note that the acct(2) system call and its API are awkward and risky. Modern systems barely use it, and developers suggest it should eventually be retired altogether.
If you must use older kernels, restrict the use of acct(2) to trusted users.
- Avoid pointing process accounting at unusual files (like those in /sys).
References
- Linux Kernel Mailing List discussion: LKML Thread
- Commit fixing the bug: git.kernel.org patch
- acct(2) man page
Summary
CVE-2025-21846 is a Linux kernel bug where writing process accounting data to special files could crash the system. The developers fixed it by ensuring the actual file write happens in a safe, known-good kernel context via a workqueue. Though not a remote exploit, it's a good reminder that legacy APIs can hide modern dangers. Upgrade your kernel to stay secure!
*Exclusively written and simplified for this post.*
Timeline
Published on: 03/12/2025 10:15:16 UTC
Last modified on: 05/04/2025 07:22:26 UTC