On March 2024, security researchers disclosed CVE-2024-27058, a race condition in the Linux kernel’s handling of disk quota (dquot) management in tmpfs file systems. This bug, uncovered via syzkaller, can trigger kernel warnings and theoretically create conditions ripe for further security issues—a serious concern for those running multi-user or containerized environments.

This article gives an easy-to-follow explanation of the bug, its impact, code details, and how it was fixed.

The Problem: Race on dquot rbtree

Disk quotas (dquot) help limit storage usage per user or group on filesystems like tmpfs. Under the hood, kernel code uses a red-black tree (rbtree) for efficient dquot storage and lookups. The kernel also provides special synchronization primitives (like semaphores) to coordinate access between threads.

Thread 2 is also working with dquots (shmem_{acquire,release}_dquot()).

If both threads fetch the rbtree root at the same time without locking, but only lock later, one thread might see a changed tree after a rebalance operation, causing it to miss nodes or trigger warnings.

In simple terms:
The kernel needs to lock access _before_ looking at the tree root, or it risks looking in the wrong place—much like grabbing a deck of shuffled cards while someone else is in the middle of another four-card shuffle.

Timeline Example

| Thread 1 | Thread 2 |
|----------------------------------|----------------------------------|
| shmem_release_dquot() | shmem_{acquire,release}_dquot() |
| fetch ROOT | fetch ROOT |
| *(waits to acquire dqio_sem)* | *acquires dqio_sem* |
| | *rebalance tree, release dqio_sem* |
| acquires dqio_sem | |
| searches from old root location | |

Result: Thread 1 searches from a now-outdated root, missing the right node, triggering a kernel warning.

Vulnerable code (simplified)

struct rb_node *node = dqopt->root; // Get tree root WITHOUT locking!
down_read(&dqopt->dqio_sem);
// ... now try searching the tree

What’s wrong:
The root might have changed while waiting to acquire the semaphore, leading to a stale pointer!

Patched code

down_read(&dqopt->dqio_sem);             // First, lock the semaphore
struct rb_node *node = dqopt->root;      // Only then, get the root
// ... safe to search the tree

Why it works:
Getting the semaphore first blocks concurrent modifications. Only then do we look up the root node.

- Linux kernel commit fixing CVE-2024-27058 (lkml.org link)
- syzkaller bug report
- NVD entry for CVE-2024-27058

Can it be exploited?

- Kernel warnings: The current PoC (proof of concept) only triggers a warning, not a full exploit.
- Denial of Service: In some kernel builds with strict settings (like panic on warnings), this could kill your system.
- Potential for privilege escalation: If another bug makes this warning turn into a use-after-free or memory corruption, attackers could combine bugs for more serious attacks.

Example syzkaller reproducer

From the syzkaller report, you can trigger this by repeatedly adding/removing disk quotas on tmpfs files—especially from parallel processes.

Warning: Running this code on a production server can crash it! Only test in a VM for research.

Who is affected?

- Any Linux kernel with tmpfs + user/group disk quotas enabled (and not yet patched)
- Unprivileged users may not directly trigger this, but shared hosting/containers increase the risk

How to fix

- Apply the official patch in your kernel source tree, or

Conclusion

CVE-2024-27058 is a subtle race condition from improper locking in Linux tmpfs disk quotas. While initially causing warnings, such bugs can turn into bigger issues—reminding us that even high-quality kernel code benefits from strong fuzzing and careful race condition management. Patching ASAP protects your systems from both subtle instability and potential security escalation.

Further Reading

- Red-Black Trees in the Linux Kernel
- Managing Disk Quotas in Linux

Timeline

Published on: 05/01/2024 13:15:50 UTC
Last modified on: 11/01/2024 17:35:04 UTC