kernel BUG in vfs_get_tree (3)

Status: upstream: reported C repro on 2026/11/14 14:27
Subsystems: squashfs
Labels: prio:normal
[Documentation on labels]
Reported-by: syzbot+7b1d0ea11475e857d063@syzkaller.appspotmail.com
First crash: 13h59m, last: 41m
✨ AI-generated root cause summary:

In squashfs_read_inode(), reading directory metadata via squashfs_read_metadata() returns the positive number of bytes read (32 for SQUASHFS_DIR_TYPE and 40 for SQUASHFS_LDIR_TYPE). When the directory size sanity check fails (inode->i_size < 3), the code jumps to failed_read without setting err to a negative errno such as -EINVAL. Consequently, squashfs_read_inode() returns positive 40 (or 32), which propagates up through squashfs_fill_super() and get_tree_bdev() to vfs_get_tree(). Because vfs_get_tree() only checks for error < 0, it observes a positive return value without fc->root being populated, triggering an explicit kernel BUG().

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit 84abb955b101:

Technical Analysis of Kernel BUG at fs/super.c:2174

1. Inode Reading Logic in SquashFS (fs/squashfs/inode.c)

When reading SquashFS inodes in squashfs_read_inode(), directory inodes of type SQUASHFS_DIR_TYPE and SQUASHFS_LDIR_TYPE are decoded as follows:

		case SQUASHFS_DIR_TYPE: {
			struct squashfs_dir_inode *sqsh_ino = &squashfs_ino.dir;

			err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
					sizeof(*sqsh_ino));
			if (err < 0)
				goto failed_read;

			/* The directory size must be 3 or larger, as it includes "." and ".." entries */
			inode->i_size = le16_to_cpu(sqsh_ino->file_size);
			if (inode->i_size < 3)
				goto failed_read;
...
		case SQUASHFS_LDIR_TYPE: {
			struct squashfs_ldir_inode *sqsh_ino = &squashfs_ino.ldir;

			err = squashfs_read_metadata(sb, sqsh_ino, &block, &offset,
					sizeof(*sqsh_ino));
			if (err < 0)
				goto failed_read;

			/* The directory size must be 3 or larger, as it includes "." and ".." entries */
			inode->i_size = le32_to_cpu(sqsh_ino->file_size);
			if (inode->i_size < 3)
				goto failed_read;

In squashfs_read_metadata() (fs/squashfs/cache.c:438-477), on success, the function returns the number of bytes read (res = length). Thus, err is assigned:

  • sizeof(struct squashfs_dir_inode) = 32 for SQUASHFS_DIR_TYPE
  • sizeof(struct squashfs_ldir_inode) = 40 for SQUASHFS_LDIR_TYPE

Immediately following squashfs_read_metadata(), SquashFS performs a directory sanity check: a directory must have a size of at least 3 bytes (accounting for . and .. entries). When inode->i_size < 3, execution jumps to failed_read: (fs/squashfs/inode.c:462):

	failed_read:
		ERROR("Unable to read inode 0x%llx\n", ino);
		return err;

Crucially, neither case SQUASHFS_DIR_TYPE nor case SQUASHFS_LDIR_TYPE sets err = -EINVAL or any other negative error code before jumping to failed_read:. Consequently, squashfs_read_inode() logs:

SQUASHFS error: Unable to read inode 0x11f

and returns the positive value 40 (or 32).

2. Mount Failure and VFS Invariant Violation

During filesystem mounting:

  1. squashfs_fill_super() (fs/squashfs/super.c:493) calls err = squashfs_read_inode(root, root_inode); to initialize the root inode.
  2. Because err is positive 40 (non-zero), if (err) evaluates to true. squashfs_fill_super() destroys the root inode, tears down allocated structures, leaves sb->s_root = NULL, and returns err = 40.
  3. squashfs_get_tree() delegates to get_tree_bdev() / get_tree_bdev_flags() (fs/super.c:2104-2108). It sees error = fill_super(s, fc); is non-zero, deactivates the superblock, does not populate fc->root, and returns 40.
  4. Control returns to vfs_get_tree() (fs/super.c:2153-2175):
    	error = fc->ops->get_tree(fc);
    	if (error < 0)
    		return error;
    
    	if (!fc->root) {
    		pr_err("Filesystem %s get_tree() didn't set fc->root, returned %i\n",
    		       fc->fs_type->name, error);
    		/* We don't know what the locking state of the superblock is -
    		 * if there is a superblock.
    		 */
    		BUG();
    	}
    
  5. Because error is 40 (positive), the if (error < 0) error check does not trigger. Since fc->root is NULL, vfs_get_tree() concludes that the filesystem's ->get_tree() operation improperly succeeded without setting fc->root, logs "Filesystem squashfs get_tree() didn't set fc->root, returned 40", and calls BUG().
▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
4ff74488 assessment-security DenialOfService: ✅ Exploitable: ❌ FilesystemTrigger: ✅ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ kernel BUG in vfs_get_tree (3) 2026/11/14 01:09 2026/11/14 01:09 2026/11/14 01:44 819ebe34
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [squashfs?] kernel BUG in vfs_get_tree (3) 0 (1) 2026/11/14 14:27
▶ ▼ Similar bugs (2)
Kernel Title Rank 🛈 Repro Cause bisect Fix bisect Count Last Reported Patched Status
upstream kernel BUG in vfs_get_tree (2) fs -1 syz, C done 22 527d 524d 29/29 fixed on 2025/07/16 19:06
upstream kernel BUG in vfs_get_tree fs -1 syz, C done 318 771d 814d 28/29 fixed on 2024/10/22 11:57

Sample crash report:
loop0: detected capacity change from 0 to 8
SQUASHFS error: Unable to read inode 0x11f
Filesystem squashfs get_tree() didn't set fc->root, returned 40
------------[ cut here ]------------
kernel BUG at fs/super.c:2174!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 0 UID: 0 PID: 5645 Comm: syz-executor247 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/06/2026
RIP: 0010:vfs_get_tree+0x29c/0x2a0 fs/super.c:2174
Code: 1b 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 07 2b eb ff 48 8b 33 48 c7 c7 00 6b 40 8c 44 89 f2 e8 85 81 c9 fe 90 <0f> 0b 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f
RSP: 0018:ffffc90003a67c88 EFLAGS: 00010246
RAX: 000000000000003f RBX: ffffffff903c9a60 RCX: f236a142641ab000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc90003a67df0 R08: ffffffff9014d12b R09: 1ffffffff2029a25
R10: dffffc0000000000 R11: fffffbfff2029a26 R12: 1ffff11003b5f455
R13: dffffc0000000000 R14: 0000000000000028 R15: 0000000000000000
FS:  0000555561a2d400(0000) GS:ffff8881233cd000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffd3ab27000 CR3: 000000007b7a8000 CR4: 00000000003526f0
Call Trace:
 <TASK>
 fc_mount fs/namespace.c:1300 [inline]
 do_new_mount_fc fs/namespace.c:4030 [inline]
 do_new_mount+0x325/0xb00 fs/namespace.c:4106
 do_mount fs/namespace.c:4470 [inline]
 __do_sys_mount fs/namespace.c:4683 [inline]
 __se_sys_mount+0x31d/0x420 fs/namespace.c:4660
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x171/0x540 arch/x86/entry/syscall_64.c:89
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x00007f7481046aca
Code: 56 53 b8 9d 00 00 00 0f 05 83 f8 ea 75 a2 c7 05 c4 ff 08 00 00 00 00 00 eb 96 e8 51 05 00 00 90 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 d8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd3ab26658 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007ffd3ab26680 RCX: 00007f7481046aca
RDX: 00002000000001c0 RSI: 0000200000000200 RDI: 00007ffd3ab26680
RBP: 00002000000001c0 R08: 00007ffd3ab266c0 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000206 R12: 0000200000000200
R13: 00007ffd3ab266c0 R14: 0000000000000003 R15: 0000000000000000
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:vfs_get_tree+0x29c/0x2a0 fs/super.c:2174
Code: 1b 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 07 2b eb ff 48 8b 33 48 c7 c7 00 6b 40 8c 44 89 f2 e8 85 81 c9 fe 90 <0f> 0b 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f
RSP: 0018:ffffc90003a67c88 EFLAGS: 00010246
RAX: 000000000000003f RBX: ffffffff903c9a60 RCX: f236a142641ab000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: ffffc90003a67df0 R08: ffffffff9014d12b R09: 1ffffffff2029a25
R10: dffffc0000000000 R11: fffffbfff2029a26 R12: 1ffff11003b5f455
R13: dffffc0000000000 R14: 0000000000000028 R15: 0000000000000000
FS:  0000555561a2d400(0000) GS:ffff8881233cd000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffd3ab27000 CR3: 000000007b7a8000 CR4: 00000000003526f0

Crashes (9):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/14 14:26 linux-next 84abb955b101 819ebe34 .config strace log report syz / log C [disk image] [vmlinux] [kernel image] [mounted in repro] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 03:46 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 03:46 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 03:05 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 03:01 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 02:46 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 02:38 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 01:09 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
2026/11/14 01:08 linux-next 84abb955b101 be5d1971 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-linux-next-kasan-gce-root kernel BUG in vfs_get_tree
* Struck through repros no longer work on HEAD.