CVE-2021-46972 - Dentry Leak in Linux Kernel OverlayFS — Detailed Analysis & Exploit Guide

One of the lesser-known but impactful Linux kernel vulnerabilities in recent years is CVE-2021-46972, which relates to a dentry leak in overlayfs due to incorrect handling of temporary dentries on errors. In simple words, this bug could leave behind memory objects (dentrites) when special filesystem events fail, causing resource leaks and trouble shutting down those filesystems.

This long read will *exclusively* walk through the background, technical details, actual code changes, and show how you can trigger (and verify!) this leak. Whether you’re patching systems or hacking for fun—here’s what you need to know.

[References](#references)

Background: What is a Dentry Leak?

In Linux filesystems, a dentry (directory entry) is a "memory structure" mapping filenames to inodes (file objects). When filesystems mount, unmount, or handle complex actions, these dentries are created and managed in memory.

A dentry leak happens if the kernel fails to release (free) these structures—usually due to a subtle error during special file operations. Over time, this can make mounting/unmounting slow, cause out-of-memory issues, or expose tricky kernel bugs exploitable for privilege escalations.


The bug appeared after this commit

> 6815f479ca90 ("ovl: use only uppermetacopy state in ovl_lookup()")

The problem? If there was a metacopy error during file lookup, overlayfs failed to *put* (release) a temporary dentry it created. That meant each error leaked a small chunk of memory. After repeated operations, these built up in the kernel, causing warnings on unmount:

overlayfs: refusing to follow metacopy origin for (/file)
...
BUG: Dentry (____ptrval____){i=3f33,n=file3}  still in use (1) [unmount of overlay overlay]
...
WARNING: ... at umount_check.cold+x107/x14d
...
VFS: Busy inodes after unmount of overlay. Self-destruct in 5 seconds.  Have a nice day...

This wasn't just ugly: it could let a userlock down system memory by repeatedly triggering the leak.

The logic in ovl_lookup() was like

if (meta_error) {
    // forgot to release temp dentry!
    return ERR_PTR(meta_error);
}
// ... rest of function ...

It should have freed the temporary dentry on error.


How Was It Fixed?

The fix is a one-line change—just release the dentry on error!

Patched code

if (meta_error) {
    dput(upperdentry);  // Free the dentry!
    return ERR_PTR(meta_error);
}

Let’s see the relevant snippet

// in fs/overlayfs/namei.c (simplified)
if (meta_error) {
    dput(upperdentry);         // Fix: properly free dentry on error
    return ERR_PTR(meta_error);
}

Read the upstream patch here (kernel.org)


Reproducing & Exploiting the Leak

This leak is easy to verify with a tool like syzkaller or a crafted user scenario.

Create a lowerdir/ and upperdir/ and workdir/ -- then mount overlay

mkdir lower upper work overlay
touch lower/file

mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work overlay

### Step 2: (Optionally) Corrupt/Trigger Metacopy

A metacopy error needs metacopy-enabled files. You can force it or use syzkaller recipes; for simplicity, tools like syzkaller can automate the error generation.

Try accessing a file that will cause a metacopy error, e.g., via

# This is a stand-in, actual trigger may require corrupting metacopy xattrs
cat overlay/file

If the system is vulnerable you’ll get kernel logs like

overlayfs: refusing to follow metacopy origin for (/file)

Step 4: Unmount and Observe

umount overlay
dmesg | tail

If unpatched

BUG: Dentry (....) still in use (1) [unmount of overlay overlay]
VFS: Busy inodes after unmount of overlay. Self-destruct in 5 seconds. Have a nice day...

Step 5: Syzkaller Automated Reproducer

The fix was tested using a syzkaller reproducer (a kernel fuzzing tool).

More details

- Syzkaller: How to run
- Upstream discussion thread


References

- CVE-2021-46972 at cve.mitre.org
- Linux Kernel Patch (kernel.org)
- OverlayFS Documentation (kernel.org)
- Syzkaller Kernel Fuzzer

Summary

CVE-2021-46972 is a classic example of how a tiny code omission can cause persistent resource leaks in something as fundamental as the Linux kernel. Even if the bug “just” leaks memory, it puts system stability at risk, especially at scale.

Patch your kernels, and remind your friends: always dput your dentries!

*Exclusive breakdown by ChatGPT — please credit original kernel authors and see references for full details.*

Timeline

Published on: 02/27/2024 19:04:07 UTC
Last modified on: 01/08/2025 17:30:28 UTC