{
"title": "CVE-2026-46164 Btrfs Double-Free: One-Line Kernel Fix for Linux Storage Security",
"content": "On May 28, 2026, the National Vulnerability Database assigned CVE-2026-46164 to a double-free flaw in the Linux kernel’s Btrfs filesystem. The bug lurks in a failure handling path when sysfs kobjects for Btrfs space-info sub-groups cannot be initialized. The fix: a single line change that replaces a reckless kfree() with a safe kobjectput(). Despite its simplicity, the vulnerability can destabilize systems or grant attackers local root access.
The flaw became public when NVD published the entry, though the patch had already flowed into the mainline kernel weeks earlier under coordinated disclosure. The incident exposes a classic pitfall in kernel programming—mishandling kobject lifecycle during error conditions. Btrfs, the default filesystem in Fedora and widely used in enterprise SUSE and Ubuntu deployments, amplifies the risk: millions of servers and containers could be affected.
What is CVE-2026-46164?
CVE-2026-46164 describes a double-free condition in the Btrfs kernel module. Double-free bugs occur when a memory block is released more than once. The kernel’s slab allocator cannot tolerate such misbehavior; a double-free often leads to immediate crash or, with careful heap grooming, arbitrary code execution.
The root cause lies in the function responsible for creating sysfs entries for Btrfs block group space information. Btrfs organizes its disk space into “spaceinfo” structures that track usage per profile (data, metadata, system). Each spaceinfo can have sub-groups, and those sub-groups are exposed via sysfs at paths like /sys/fs/btrfs/<uuid>/allocation/<profile>/. To expose a sub-group, the kernel calls kobjectinitandadd() to create a kobject and attach it to the filesystem’s sysfs tree.
If kobjectinitandadd() fails—perhaps due to a name collision or an out-of-memory condition—the invoking code must clean up. The correct approach is to call kobjectput() on the kobject, which handles reference counting and eventual freeing via a registered release function. The vulnerability emerged because the Btrfs code called kfree() directly on the sub-group structure instead, double-freeing the memory when the kobject core also eventually frees the same object.
Technical Breakdown: Kobject Lifecycle and the Error Path
Kobjects are the atomic units of sysfs. They are embedded within larger structures, and their release callbacks are responsible for freeing the container. The function kobjectinitandadd() does two things: initializes the kobject fields and adds it to sysfs. On failure, it undoes the addition but does not release the initialization reference. The caller must release that reference using kobjectput().
The Btrfs sub-group creation pseudo-code before the fix looked like:
c
static int btrfscreatespaceinfosubgroup(...) {
struct btrfsspaceinfosubgroup sg;
sg = kzalloc(sizeof(sg), GFPKERNEL);
if (!sg)
return -ENOMEM;
kobjectinit(&sg->kobj, &btrfsspaceinfosubgroupktype);
ret = kobjectadd(&sg->kobj, parent, \"%s\", name);
if (ret) {
kfree(sg); // ← THE BUG: double-free possible
return ret;
}
...
}
After kobjectinit(), the kobject has a reference count of 1. kobjectadd() may increase that count (e.g., when linking the object into sysfs). If kobjectadd() fails, it decrements the count back, but on some failure paths it may already call kobjectput() internally, decrementing the count further. If the count reaches zero during that internal cleanup, the release callback frees sg. Then the caller’s kfree(sg) frees it again.
Even if the count doesn’t reach zero immediately, the kobject still holds a reference, and when the parent is released later, a cascading kobjectput() on the child will trigger the release and free sg again. The result is undefined behavior, but typically the slab allocator detects the double-free and BUGs the kernel.
The fix, as mentioned, is a single line:
diff
kfree(sg);
+ kobject_put(&sg->kobj);
This ensures that the release callback runs exactly when the last reference is dropped, and the container is freed exactly once.
Discovery and Disclosure Timeline
The vulnerability was discovered by a kernel developer during a routine review of Btrfs sysfs error handling. The developer noticed the pattern—common in many drivers—and reported it privately to the linux-btrfs mailing list. A fix was prepared and landed in the upstream kernel on April 14, 2026, under commit btrfs: fix double-free of space-info sub-group on sysfs error. The maintainers marked it for backport to stable kernels.
The Red Hat security team triaged the bug and recognized its severity, coordinating with the Linux kernel security team. NVD published CVE-2026-46164 on May 28, 2026, as the fix propagated through distribution channels. No exploit code has been publicly observed, but the predictable nature of the bug makes proof-of-concept development straightforward.
Impact and Exploitability
The immediate threat is denial-of-service. Any local user who can mount a Btrfs filesystem or trigger space-info operations (e.g., by balancing, device reorganization) can force the creation of sysfs sub-groups and potentially hit the error path. This might be as simple as creating a specially crafted Btrfs image or