fs/super.c | 5 +++++ 1 file changed, 5 insertions(+)
In get_tree_bdev_flags(), sget_dev() calls sget_fc(), which transfers
ownership of fc->s_fs_info to the new superblock (s->s_fs_info) and
clears fc->s_fs_info. If setup_bdev_super() then fails, the superblock
is torn down via deactivate_locked_super(). However,
generic_shutdown_super() only calls the filesystem's ->put_super()
when sb->s_root is non-NULL. Since setup_bdev_super() fails before
fill_super() runs, sb->s_root is never set, so ->put_super() is never
called and the allocated s_fs_info is leaked.
Return ownership of s_fs_info to fc when setup_bdev_super() fails so
put_fs_context() can free it via the filesystem's ->free() callback.
Clear s->s_fs_info to avoid a stale reference. Do this only when
setup_bdev_super() fails; when fill_super() fails, it already frees
s_fs_info in its own error path.
Reported-by: syzbot+99f6ed51479b86ac4c41@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=99f6ed51479b86ac4c41
Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
---
fs/super.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/super.c b/fs/super.c
index 3d85265d1400..1aa8dbd19bb6 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1687,6 +1687,11 @@ int get_tree_bdev_flags(struct fs_context *fc,
}
} else {
error = setup_bdev_super(s, fc->sb_flags, fc);
+ if (error) {
+ fc->s_fs_info = s->s_fs_info;
+ s->s_fs_info = NULL;
+ }
+
if (!error)
error = fill_super(s, fc);
if (error) {
--
2.34.1
syzbot ci has tested the following series [v1] fs/super: fix s_fs_info leak when setup_bdev_super() fails https://lore.kernel.org/all/20260201073226.3445853-1-shardul.b@mpiricsoftware.com * [PATCH] fs/super: fix s_fs_info leak when setup_bdev_super() fails and found the following issues: * general protection fault in erofs_kill_sb * general protection fault in fuse_kill_sb_blk * general protection fault in ntfs3_kill_sb * general protection fault in xfs_mount_free Full report is available here: https://ci.syzbot.org/series/34ca307f-9eb2-40cb-881d-22abe7ea1c0b *** general protection fault in erofs_kill_sb tree: linux-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next base: 602544773763da411ffa67567fa1d146f3a40231 arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/ff62b70a-8cc2-476e-8c76-3012c5b4ad76/config C repro: https://ci.syzbot.org/findings/a774c7af-2849-4e3d-ae0d-489b13e32852/c_repro syz repro: https://ci.syzbot.org/findings/a774c7af-2849-4e3d-ae0d-489b13e32852/syz_repro EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: writeback. ext4 filesystem being mounted at /0/bus supports timestamps until 2038-01-19 (0x7fffffff) /dev/loop0: Can't open blockdev Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] CPU: 1 UID: 0 PID: 5991 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:erofs_kill_sb+0x4c/0x190 fs/erofs/super.c:906 Code: 9f 38 06 00 00 48 89 dd 48 c1 ed 03 42 80 7c 2d 00 00 74 08 48 89 df e8 82 83 eb fd 4c 8b 33 4d 8d 66 10 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 65 83 eb fd 49 83 3c 24 00 74 0f RSP: 0018:ffffc900039e7b58 EFLAGS: 00010202 RAX: 0000000000000002 RBX: ffff88816ed88638 RCX: ffff88816c548000 RDX: 0000000000000000 RSI: ffffffff8dad1d20 RDI: ffff88816ed88000 RBP: 1ffff1102ddb10c7 R08: ffffffff8fcec177 R09: 1ffffffff1f9d82e R10: dffffc0000000000 R11: ffffffff843ef960 R12: 0000000000000010 R13: dffffc0000000000 R14: 0000000000000000 R15: ffff88816ed88000 FS: 000055558ffb4500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b30763fff CR3: 00000001127bc000 CR4: 00000000000006f0 Call Trace: <TASK> deactivate_locked_super+0xbc/0x130 fs/super.c:474 get_tree_bdev_flags+0x4b4/0x560 fs/super.c:1698 vfs_get_tree+0x92/0x2a0 fs/super.c:1756 fc_mount fs/namespace.c:1199 [inline] do_new_mount_fc fs/namespace.c:3636 [inline] do_new_mount+0x329/0xa50 fs/namespace.c:3712 do_mount fs/namespace.c:4035 [inline] __do_sys_mount fs/namespace.c:4224 [inline] __se_sys_mount+0x31d/0x420 fs/namespace.c:4201 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf0/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f3a7139acb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff10bbdc58 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 00007f3a71615fa0 RCX: 00007f3a7139acb9 RDX: 0000200000000700 RSI: 00002000000006c0 RDI: 0000200000000640 RBP: 00007f3a71408bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000004 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f3a71615fac R14: 00007f3a71615fa0 R15: 00007f3a71615fa0 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:erofs_kill_sb+0x4c/0x190 fs/erofs/super.c:906 Code: 9f 38 06 00 00 48 89 dd 48 c1 ed 03 42 80 7c 2d 00 00 74 08 48 89 df e8 82 83 eb fd 4c 8b 33 4d 8d 66 10 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 65 83 eb fd 49 83 3c 24 00 74 0f RSP: 0018:ffffc900039e7b58 EFLAGS: 00010202 RAX: 0000000000000002 RBX: ffff88816ed88638 RCX: ffff88816c548000 RDX: 0000000000000000 RSI: ffffffff8dad1d20 RDI: ffff88816ed88000 RBP: 1ffff1102ddb10c7 R08: ffffffff8fcec177 R09: 1ffffffff1f9d82e R10: dffffc0000000000 R11: ffffffff843ef960 R12: 0000000000000010 R13: dffffc0000000000 R14: 0000000000000000 R15: ffff88816ed88000 FS: 000055558ffb4500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b30763fff CR3: 00000001127bc000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 9f lahf 1: 38 06 cmp %al,(%rsi) 3: 00 00 add %al,(%rax) 5: 48 89 dd mov %rbx,%rbp 8: 48 c1 ed 03 shr $0x3,%rbp c: 42 80 7c 2d 00 00 cmpb $0x0,0x0(%rbp,%r13,1) 12: 74 08 je 0x1c 14: 48 89 df mov %rbx,%rdi 17: e8 82 83 eb fd call 0xfdeb839e 1c: 4c 8b 33 mov (%rbx),%r14 1f: 4d 8d 66 10 lea 0x10(%r14),%r12 23: 4c 89 e0 mov %r12,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction 2f: 74 08 je 0x39 31: 4c 89 e7 mov %r12,%rdi 34: e8 65 83 eb fd call 0xfdeb839e 39: 49 83 3c 24 00 cmpq $0x0,(%r12) 3e: 74 0f je 0x4f *** general protection fault in fuse_kill_sb_blk tree: linux-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next base: 602544773763da411ffa67567fa1d146f3a40231 arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/ff62b70a-8cc2-476e-8c76-3012c5b4ad76/config C repro: https://ci.syzbot.org/findings/23ab56a2-425c-4ce8-ba8d-1743bb4b889d/c_repro syz repro: https://ci.syzbot.org/findings/23ab56a2-425c-4ce8-ba8d-1743bb4b889d/syz_repro EXT4-fs (loop0): 1 orphan inode deleted EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 ro without journal. Quota mode: writeback. /dev/loop0: Can't open blockdev Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 UID: 0 PID: 5983 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:fuse_mount_destroy fs/fuse/inode.c:2118 [inline] RIP: 0010:fuse_kill_sb_blk+0x210/0x270 fs/fuse/inode.c:2145 Code: fe 4c 89 ff e8 d1 b5 ff ff 48 89 ef e8 79 5d 00 ff 43 80 3c 2e 00 74 08 48 89 df e8 0a da ed fe 48 8b 1b 48 89 d8 48 c1 e8 03 <42> 80 3c 28 00 74 08 48 89 df e8 f1 d9 ed fe 48 8b 3b e8 f9 6a ff RSP: 0018:ffffc90003c17af8 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff888118069d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 00000000ffffffff RBP: ffff8881168e0000 R08: ffff8881168e0077 R09: 1ffff11022d1c00e R10: dffffc0000000000 R11: ffffed1022d1c00f R12: ffff8881168e0068 R13: dffffc0000000000 R14: 1ffff11022d1c0c7 R15: 0000000000000000 FS: 0000555591c2f500(0000) GS:ffff88818e342000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000200000002000 CR3: 00000001115be000 CR4: 00000000000006f0 Call Trace: <TASK> deactivate_locked_super+0xbc/0x130 fs/super.c:474 get_tree_bdev_flags+0x4b4/0x560 fs/super.c:1698 fuse_get_tree+0x23c/0x4f0 fs/fuse/inode.c:2003 vfs_get_tree+0x92/0x2a0 fs/super.c:1756 fc_mount fs/namespace.c:1199 [inline] do_new_mount_fc fs/namespace.c:3636 [inline] do_new_mount+0x329/0xa50 fs/namespace.c:3712 do_mount fs/namespace.c:4035 [inline] __do_sys_mount fs/namespace.c:4224 [inline] __se_sys_mount+0x31d/0x420 fs/namespace.c:4201 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf0/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f29dd79acb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fffc5c2bf88 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 00007f29dda15fa0 RCX: 00007f29dd79acb9 RDX: 0000200000000080 RSI: 0000200000000040 RDI: 0000200000000000 RBP: 00007f29dd808bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000003000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f29dda15fac R14: 00007f29dda15fa0 R15: 00007f29dda15fa0 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:fuse_mount_destroy fs/fuse/inode.c:2118 [inline] RIP: 0010:fuse_kill_sb_blk+0x210/0x270 fs/fuse/inode.c:2145 Code: fe 4c 89 ff e8 d1 b5 ff ff 48 89 ef e8 79 5d 00 ff 43 80 3c 2e 00 74 08 48 89 df e8 0a da ed fe 48 8b 1b 48 89 d8 48 c1 e8 03 <42> 80 3c 28 00 74 08 48 89 df e8 f1 d9 ed fe 48 8b 3b e8 f9 6a ff RSP: 0018:ffffc90003c17af8 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff888118069d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 00000000ffffffff RBP: ffff8881168e0000 R08: ffff8881168e0077 R09: 1ffff11022d1c00e R10: dffffc0000000000 R11: ffffed1022d1c00f R12: ffff8881168e0068 R13: dffffc0000000000 R14: 1ffff11022d1c0c7 R15: 0000000000000000 FS: 0000555591c2f500(0000) GS:ffff88818e342000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000200000002000 CR3: 00000001115be000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: fe 4c 89 ff decb -0x1(%rcx,%rcx,4) 4: e8 d1 b5 ff ff call 0xffffb5da 9: 48 89 ef mov %rbp,%rdi c: e8 79 5d 00 ff call 0xff005d8a 11: 43 80 3c 2e 00 cmpb $0x0,(%r14,%r13,1) 16: 74 08 je 0x20 18: 48 89 df mov %rbx,%rdi 1b: e8 0a da ed fe call 0xfeedda2a 20: 48 8b 1b mov (%rbx),%rbx 23: 48 89 d8 mov %rbx,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction 2f: 74 08 je 0x39 31: 48 89 df mov %rbx,%rdi 34: e8 f1 d9 ed fe call 0xfeedda2a 39: 48 8b 3b mov (%rbx),%rdi 3c: e8 .byte 0xe8 3d: f9 stc 3e: 6a ff push $0xffffffffffffffff *** general protection fault in ntfs3_kill_sb tree: linux-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next base: 602544773763da411ffa67567fa1d146f3a40231 arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/ff62b70a-8cc2-476e-8c76-3012c5b4ad76/config C repro: https://ci.syzbot.org/findings/701e05cd-daef-4ecc-9716-2188883c4d68/c_repro syz repro: https://ci.syzbot.org/findings/701e05cd-daef-4ecc-9716-2188883c4d68/syz_repro F2FS-fs (loop0): f2fs_recover_fsync_data: recovery fsync data, check_only: 0 F2FS-fs (loop0): Try to recover 1th superblock, ret: 0 F2FS-fs (loop0): Mounted with checkpoint version = 48b305e5 /dev/loop0: Can't open blockdev Oops: general protection fault, probably for non-canonical address 0xdffffc0000000137: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x00000000000009b8-0x00000000000009bf] CPU: 1 UID: 0 PID: 5980 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:ntfs3_kill_sb+0x52/0x1c0 fs/ntfs3/super.c:1864 Code: 03 42 80 3c 38 00 74 05 e8 6b 1f 0f ff 49 8b 9e 38 06 00 00 4c 89 f7 e8 bc a2 21 ff 4c 8d b3 b8 09 00 00 4c 89 f0 48 c1 e8 03 <42> 80 3c 38 00 74 08 4c 89 f7 e8 3f 1f 0f ff 4d 8b 36 4d 85 f6 74 RSP: 0018:ffffc90004087b70 EFLAGS: 00010202 RAX: 0000000000000137 RBX: 0000000000000000 RCX: ffff88810a281d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 00000000ffffffff RBP: ffffc90004087c00 R08: ffff88811696a077 R09: 1ffff11022d2d40e R10: dffffc0000000000 R11: ffffed1022d2d40f R12: dffffc0000000000 R13: ffff88811696a638 R14: 00000000000009b8 R15: dffffc0000000000 FS: 00005555632f0500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f12cce706c0 CR3: 0000000173c4e000 CR4: 00000000000006f0 Call Trace: <TASK> deactivate_locked_super+0xbc/0x130 fs/super.c:474 get_tree_bdev_flags+0x4b4/0x560 fs/super.c:1698 vfs_get_tree+0x92/0x2a0 fs/super.c:1756 fc_mount fs/namespace.c:1199 [inline] do_new_mount_fc fs/namespace.c:3636 [inline] do_new_mount+0x329/0xa50 fs/namespace.c:3712 do_mount fs/namespace.c:4035 [inline] __do_sys_mount fs/namespace.c:4224 [inline] __se_sys_mount+0x31d/0x420 fs/namespace.c:4201 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf0/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f12ccf9acb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffeb8b65048 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 00007f12cd215fa0 RCX: 00007f12ccf9acb9 RDX: 00002000000000c0 RSI: 0000200000000180 RDI: 0000200000000100 RBP: 00007f12cd008bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f12cd215fac R14: 00007f12cd215fa0 R15: 00007f12cd215fa0 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:ntfs3_kill_sb+0x52/0x1c0 fs/ntfs3/super.c:1864 Code: 03 42 80 3c 38 00 74 05 e8 6b 1f 0f ff 49 8b 9e 38 06 00 00 4c 89 f7 e8 bc a2 21 ff 4c 8d b3 b8 09 00 00 4c 89 f0 48 c1 e8 03 <42> 80 3c 38 00 74 08 4c 89 f7 e8 3f 1f 0f ff 4d 8b 36 4d 85 f6 74 RSP: 0018:ffffc90004087b70 EFLAGS: 00010202 RAX: 0000000000000137 RBX: 0000000000000000 RCX: ffff88810a281d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 00000000ffffffff RBP: ffffc90004087c00 R08: ffff88811696a077 R09: 1ffff11022d2d40e R10: dffffc0000000000 R11: ffffed1022d2d40f R12: dffffc0000000000 R13: ffff88811696a638 R14: 00000000000009b8 R15: dffffc0000000000 FS: 00005555632f0500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f12cce706c0 CR3: 0000000173c4e000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 03 42 80 add -0x80(%rdx),%eax 3: 3c 38 cmp $0x38,%al 5: 00 74 05 e8 add %dh,-0x18(%rbp,%rax,1) 9: 6b 1f 0f imul $0xf,(%rdi),%ebx c: ff 49 8b decl -0x75(%rcx) f: 9e sahf 10: 38 06 cmp %al,(%rsi) 12: 00 00 add %al,(%rax) 14: 4c 89 f7 mov %r14,%rdi 17: e8 bc a2 21 ff call 0xff21a2d8 1c: 4c 8d b3 b8 09 00 00 lea 0x9b8(%rbx),%r14 23: 4c 89 f0 mov %r14,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 80 3c 38 00 cmpb $0x0,(%rax,%r15,1) <-- trapping instruction 2f: 74 08 je 0x39 31: 4c 89 f7 mov %r14,%rdi 34: e8 3f 1f 0f ff call 0xff0f1f78 39: 4d 8b 36 mov (%r14),%r14 3c: 4d 85 f6 test %r14,%r14 3f: 74 .byte 0x74 *** general protection fault in xfs_mount_free tree: linux-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next base: 602544773763da411ffa67567fa1d146f3a40231 arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/ff62b70a-8cc2-476e-8c76-3012c5b4ad76/config C repro: https://ci.syzbot.org/findings/5b7b1e1a-4d82-45fc-a796-e0633aa2c690/c_repro syz repro: https://ci.syzbot.org/findings/5b7b1e1a-4d82-45fc-a796-e0633aa2c690/syz_repro ======================================================= JBD2: Ignoring recovery information on journal ocfs2: Mounting device (7,0) on (node local, slot 0) with ordered data mode. /dev/loop0: Can't open blockdev Oops: general protection fault, probably for non-canonical address 0xdffffc0000000034: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] CPU: 1 UID: 0 PID: 5983 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:xfs_mount_free+0x27/0x1a0 fs/xfs/xfs_super.c:815 Code: 90 90 90 41 57 41 56 41 54 53 48 89 fb 49 bc 00 00 00 00 00 fc ff df e8 d7 f1 41 fe 4c 8d b3 a0 01 00 00 4c 89 f0 48 c1 e8 03 <42> 80 3c 20 00 74 08 4c 89 f7 e8 9a 24 a9 fe 4d 8b 36 4d 85 f6 74 RSP: 0018:ffffc90004077b68 EFLAGS: 00010202 RAX: 0000000000000034 RBX: 0000000000000000 RCX: ffff88816aad1d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 0000000000000000 RBP: ffffc90004077c00 R08: ffff8881b715c077 R09: 1ffff11036e2b80e R10: dffffc0000000000 R11: ffffed1036e2b80f R12: dffffc0000000000 R13: ffff8881b715c638 R14: 00000000000001a0 R15: ffff8881b715c768 FS: 00005555782c2500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000200000001200 CR3: 0000000174202000 CR4: 00000000000006f0 Call Trace: <TASK> deactivate_locked_super+0xbc/0x130 fs/super.c:474 get_tree_bdev_flags+0x4b4/0x560 fs/super.c:1698 vfs_get_tree+0x92/0x2a0 fs/super.c:1756 fc_mount fs/namespace.c:1199 [inline] do_new_mount_fc fs/namespace.c:3636 [inline] do_new_mount+0x329/0xa50 fs/namespace.c:3712 do_mount fs/namespace.c:4035 [inline] __do_sys_mount fs/namespace.c:4224 [inline] __se_sys_mount+0x31d/0x420 fs/namespace.c:4201 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf0/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f341a99acb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff965f4398 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 RAX: ffffffffffffffda RBX: 00007f341ac15fa0 RCX: 00007f341a99acb9 RDX: 0000200000001200 RSI: 00002000000000c0 RDI: 0000200000000240 RBP: 00007f341aa08bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 000000000280c002 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f341ac15fac R14: 00007f341ac15fa0 R15: 00007f341ac15fa0 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:xfs_mount_free+0x27/0x1a0 fs/xfs/xfs_super.c:815 Code: 90 90 90 41 57 41 56 41 54 53 48 89 fb 49 bc 00 00 00 00 00 fc ff df e8 d7 f1 41 fe 4c 8d b3 a0 01 00 00 4c 89 f0 48 c1 e8 03 <42> 80 3c 20 00 74 08 4c 89 f7 e8 9a 24 a9 fe 4d 8b 36 4d 85 f6 74 RSP: 0018:ffffc90004077b68 EFLAGS: 00010202 RAX: 0000000000000034 RBX: 0000000000000000 RCX: ffff88816aad1d40 RDX: 0000000000000000 RSI: 0000000000000008 RDI: 0000000000000000 RBP: ffffc90004077c00 R08: ffff8881b715c077 R09: 1ffff11036e2b80e R10: dffffc0000000000 R11: ffffed1036e2b80f R12: dffffc0000000000 R13: ffff8881b715c638 R14: 00000000000001a0 R15: ffff8881b715c768 FS: 00005555782c2500(0000) GS:ffff8882a9942000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000200000001200 CR3: 0000000174202000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 90 nop 1: 90 nop 2: 90 nop 3: 41 57 push %r15 5: 41 56 push %r14 7: 41 54 push %r12 9: 53 push %rbx a: 48 89 fb mov %rdi,%rbx d: 49 bc 00 00 00 00 00 movabs $0xdffffc0000000000,%r12 14: fc ff df 17: e8 d7 f1 41 fe call 0xfe41f1f3 1c: 4c 8d b3 a0 01 00 00 lea 0x1a0(%rbx),%r14 23: 4c 89 f0 mov %r14,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 80 3c 20 00 cmpb $0x0,(%rax,%r12,1) <-- trapping instruction 2f: 74 08 je 0x39 31: 4c 89 f7 mov %r14,%rdi 34: e8 9a 24 a9 fe call 0xfea924d3 39: 4d 8b 36 mov (%r14),%r14 3c: 4d 85 f6 test %r14,%r14 3f: 74 .byte 0x74 *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com.
On Sun, Feb 01, 2026 at 01:02:26PM +0530, Shardul Bankar wrote: > In get_tree_bdev_flags(), sget_dev() calls sget_fc(), which transfers > ownership of fc->s_fs_info to the new superblock (s->s_fs_info) and > clears fc->s_fs_info. If setup_bdev_super() then fails, the superblock > is torn down via deactivate_locked_super(). However, > generic_shutdown_super() only calls the filesystem's ->put_super() > when sb->s_root is non-NULL. Since setup_bdev_super() fails before > fill_super() runs, sb->s_root is never set, so ->put_super() is never > called and the allocated s_fs_info is leaked. > > Return ownership of s_fs_info to fc when setup_bdev_super() fails so > put_fs_context() can free it via the filesystem's ->free() callback. > Clear s->s_fs_info to avoid a stale reference. Do this only when > setup_bdev_super() fails; when fill_super() fails, it already frees > s_fs_info in its own error path. First of all, _what_ ->put_super()? Forget ->s_root, ->s_op is not going to be set there, so there's nowhere to get ->put_super() from. Relevant thing here is ->kill_sb(). Freeing ->s_fs_info is better done there anyway - makes for simpler handling of foo_fill_super() failure exits, exactly because you don't need to free the damn thing there - just let your ->kill_sb() deal with it. The thing is, there are ->kill_sb() instances that do just that and I'm not at all sure they won't be broken by this patch. Note that right now it's either "deactivate_locked_super() done, ->free() is told to bugger off" or "->free() is called, deactivate_locked_super() and ->kill_sb() isn't"; you are introducing a new situation here.
On Sun, 2026-02-01 at 08:27 +0000, Al Viro wrote: > On Sun, Feb 01, 2026 at 01:02:26PM +0530, Shardul Bankar wrote: > > > First of all, _what_ ->put_super()? Forget ->s_root, ->s_op is > not going to be set there, so there's nowhere to get ->put_super() > from. Relevant thing here is ->kill_sb(). > Right, good catch- at that point ->s_op isn’t set yet, so ->put_super() isn’t even a thing to rely on. Thanks for pointing that out. The leak here is actually originating from hfsplus (hfsplus_init_fs_context()). > Freeing ->s_fs_info is better done there anyway - makes for simpler > handling of foo_fill_super() failure exits, exactly because you don't > need to free the damn thing there - just let your ->kill_sb() deal > with > it. > > The thing is, there are ->kill_sb() instances that do just that and > I'm not at all sure they won't be broken by this patch. > > Note that right now it's either "deactivate_locked_super() done, - > >free() > is told to bugger off" or "->free() is called, > deactivate_locked_super() > and ->kill_sb() isn't"; you are introducing a new situation here. I see your concern about introducing a new ownership state for s_fs_info (handing it back to fc while still going through deactivate_locked_super() / ->kill_sb()), which could break filesystems that already free s_fs_info from ->kill_sb(). I'll drop this patch and raise a new one by fixing the leak in the filesystem side instead (HFS+), making sure its ->kill_sb() path reliably frees s_fs_info even when we fail before fill_super() runs, and I’ll add the HFS+ maintainer(s) on that patch. Thanks, Shardul
© 2016 - 2026 Red Hat, Inc.