[PATCH] fs: fix s_fs_info leak when setup_bdev_super() fails
From: hanzhijian
Date: Sat Aug 22 2026 - 00:11:05 EST
get_tree_bdev_flags() hands fc->s_fs_info to the newly allocated
super block in sget_fc() and clears fc->s_fs_info. If
setup_bdev_super() then fails (the block device cannot be opened, is
read-only, or is frozen), fill_super() is never called and sb->s_root
stays NULL. The cleanup path calls deactivate_locked_super(), whose
generic_shutdown_super() skips the whole sb->s_root block -- including
the put_super() callback that would otherwise release s_fs_info --
leaking the allocation made by the filesystem's init_fs_context().
Hand s_fs_info back to the fs_context when setup_bdev_super() fails so
that put_fs_context() releases it through the filesystem's free()
callback.
Reported-by: syzbot+1c70732df5fd4f0e4fbb@xxxxxxxxxxxxxxxxxxxxxxxxx
Link: https://syzkaller.appspot.com/bug?extid=1c70732df5fd4f0e4fbb
Signed-off-by: hanzhijian <hanzhijian1991@xxxxxxxxx>
---
fs/super.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/fs/super.c b/fs/super.c
index 05e443173..8b978b67b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1883,8 +1883,19 @@ int get_tree_bdev_flags(struct fs_context *fc,
}
} else {
error = setup_bdev_super(s, fc->sb_flags, fc);
- if (!error)
- error = fill_super(s, fc);
+ if (error) {
+ /*
+ * fill_super() was not called, so nothing has taken
+ * ownership of fc->s_fs_info. Hand it back so that
+ * put_fs_context() can release it, otherwise it
+ * leaks.
+ */
+ fc->s_fs_info = s->s_fs_info;
+ s->s_fs_info = NULL;
+ deactivate_locked_super(s);
+ return error;
+ }
+ error = fill_super(s, fc);
if (error) {
deactivate_locked_super(s);
return error;
--
2.43.0