[PATCH] fs: fix ramfs_fs_info leak when rootfs is unmounted
From: Karl Mehltretter
Date: Fri Oct 09 2026 - 01:57:17 EST
When rootfs is a ramfs, for example with root= on the command line, its
superblock carries a struct ramfs_fs_info from ramfs_init_fs_context().
ramfs_kill_sb() frees it, but rootfs_fs_type uses kill_anon_super().
Before commit 576ee5dfd459 ("fs: add immutable rootfs") rootfs could not
be unmounted. Since then prepare_namespace() pivots into the real root
and unmounts rootfs. When the superblock is destroyed, the structure is
leaked. kmemleak on an SH7785LCR board:
unreferenced object 0x8100a720 (size 32):
comm "swapper/0", pid 0, jiffies 4294892299
backtrace (crc c8bfd23b):
...
ramfs_init_fs_context+0x16/0x48
rootfs_init_fs_context+0x16/0x2c
alloc_fs_context+0x98/0x114
fs_context_for_mount+0x16/0x24
...
Call ramfs_kill_sb() when rootfs is a ramfs. tmpfs frees its own data
in put_super and keeps kill_anon_super().
Fixes: 576ee5dfd459 ("fs: add immutable rootfs")
Reported-by: John Paul Adrian Glaubitz <glaubitz@xxxxxxxxxxxxxxxxxxx>
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
Test: kernels with DEBUG_KMEMLEAK that mount root=/dev/sda themselves,
no initramfs. kmemleak reports the object without the patch and nothing
with it, on
- the custom QEMU model of the SH7785LCR (sh for-next plus unmerged sh
patches; 32-byte leaked allocation), and
- user-mode Linux (v7.3-rc5, um defconfig; 8-byte leaked allocation).
On the model, rootfstype=ext2,tmpfs makes rootfs a tmpfs. kmemleak
reports nothing there, with or without the patch.
The report only shows up after init reopens /dev/console. The console
that the kernel opens for init is on rootfs and keeps it alive.
---
init/do_mounts.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 95e0b3a0f711..b088021b1546 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -503,10 +503,18 @@ static int rootfs_init_fs_context(struct fs_context *fc)
return ramfs_init_fs_context(fc);
}
+static void rootfs_kill_sb(struct super_block *sb)
+{
+ if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
+ kill_anon_super(sb);
+ else
+ ramfs_kill_sb(sb);
+}
+
struct file_system_type rootfs_fs_type = {
.name = "rootfs",
.init_fs_context = rootfs_init_fs_context,
- .kill_sb = kill_anon_super,
+ .kill_sb = rootfs_kill_sb,
};
void __init init_rootfs(void)
base-commit: 72d3fcf802c45d00b300f25b848a93c3a2bd7c7e
--
2.53.0