linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
@ 2025-09-04  9:44 syzbot
  2025-09-28  7:45 ` Forwarded: [PATCH] ext4: Fix extent boundary validation in extent tree syzbot
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: syzbot @ 2025-09-04  9:44 UTC (permalink / raw)
  To: adilger.kernel, linux-ext4, linux-kernel, syzkaller-bugs, tytso

Hello,

syzbot found the following issue on:

HEAD commit:    ec299e4dc21e Merge tag 'bitmap-for-6.17-rc5' of https://gi..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1092a312580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=385d836f07b5a70d
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=12d1fe34580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=14f8de62580000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-ec299e4d.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/d15022189f21/vmlinux-ec299e4d.xz
kernel image: https://storage.googleapis.com/syzbot-assets/d73fbb71b816/bzImage-ec299e4d.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/e1c7d8ef0b25/mount_0.gz
  fsck result: OK (log: https://syzkaller.appspot.com/x/fsck.log?x=17a49e62580000)

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com

EXT4-fs (loop0): 1 truncate cleaned up
EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: none.
------------[ cut here ]------------
kernel BUG at fs/ext4/extents_status.c:1012!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 5527 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
RIP: 0010:ext4_es_cache_extent+0x698/0x700 fs/ext4/extents_status.c:1012
Code: ff df 80 3c 08 00 74 08 48 89 df e8 62 b0 b3 ff 48 8b 3b 48 8b 74 24 28 48 8d 54 24 60 e8 00 c3 0d 00 eb 14 e8 69 c0 4e ff 90 <0f> 0b e8 61 c0 4e ff eb 28 e8 5a c0 4e ff 31 f6 65 ff 0d 81 32 30
RSP: 0018:ffffc900028ff420 EFLAGS: 00010293
RAX: ffffffff8270fd97 RBX: 00000000ffffffff RCX: ffff8880330fc880
RDX: 0000000000000000 RSI: 00000000ffffffff RDI: 00000000000072ce
RBP: ffffc900028ff528 R08: ffffffff8fa3b637 R09: 1ffffffff1f476c6
R10: dffffc0000000000 R11: fffffbfff1f476c7 R12: 00000000000072d0
R13: 0000000000000008 R14: 00000000000072ce R15: dffffc0000000000
FS:  000055556eaf2500(0000) GS:ffff88808d20d000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32463fff CR3: 0000000056f56000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 ext4_cache_extents fs/ext4/extents.c:544 [inline]
 ext4_find_extent+0x482/0xcc0 fs/ext4/extents.c:928
 ext4_get_verity_descriptor_location fs/ext4/verity.c:292 [inline]
 ext4_get_verity_descriptor+0x102/0x590 fs/ext4/verity.c:346
 fsverity_get_descriptor+0x8d/0x4b0 fs/verity/open.c:323
 ensure_verity_info fs/verity/open.c:363 [inline]
 __fsverity_file_open+0xd7/0x1f0 fs/verity/open.c:384
 fsverity_file_open include/linux/fsverity.h:300 [inline]
 ext4_file_open+0x32d/0xa40 fs/ext4/file.c:909
 do_dentry_open+0x953/0x13f0 fs/open.c:965
 vfs_open+0x3b/0x340 fs/open.c:1095
 do_open fs/namei.c:3887 [inline]
 path_openat+0x2ee5/0x3830 fs/namei.c:4046
 do_filp_open+0x1fa/0x410 fs/namei.c:4073
 do_sys_openat2+0x121/0x1c0 fs/open.c:1435
 do_sys_open fs/open.c:1450 [inline]
 __do_sys_openat fs/open.c:1466 [inline]
 __se_sys_openat fs/open.c:1461 [inline]
 __x64_sys_openat+0x138/0x170 fs/open.c:1461
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f5a5878ebe9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fffa6498b18 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007f5a589c5fa0 RCX: 00007f5a5878ebe9
RDX: 0000000000000000 RSI: 0000200000000100 RDI: ffffffffffffff9c
RBP: 00007f5a58811e19 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f5a589c5fa0 R14: 00007f5a589c5fa0 R15: 0000000000000004
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:ext4_es_cache_extent+0x698/0x700 fs/ext4/extents_status.c:1012
Code: ff df 80 3c 08 00 74 08 48 89 df e8 62 b0 b3 ff 48 8b 3b 48 8b 74 24 28 48 8d 54 24 60 e8 00 c3 0d 00 eb 14 e8 69 c0 4e ff 90 <0f> 0b e8 61 c0 4e ff eb 28 e8 5a c0 4e ff 31 f6 65 ff 0d 81 32 30
RSP: 0018:ffffc900028ff420 EFLAGS: 00010293
RAX: ffffffff8270fd97 RBX: 00000000ffffffff RCX: ffff8880330fc880
RDX: 0000000000000000 RSI: 00000000ffffffff RDI: 00000000000072ce
RBP: ffffc900028ff528 R08: ffffffff8fa3b637 R09: 1ffffffff1f476c6
R10: dffffc0000000000 R11: fffffbfff1f476c7 R12: 00000000000072d0
R13: 0000000000000008 R14: 00000000000072ce R15: dffffc0000000000
FS:  000055556eaf2500(0000) GS:ffff88808d20d000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32463fff CR3: 0000000056f56000 CR4: 0000000000352ef0


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH] ext4: Fix extent boundary validation in extent tree
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
@ 2025-09-28  7:45 ` syzbot
  2025-09-28  9:11 ` Forwarded: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents syzbot
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  7:45 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] ext4: Fix extent boundary validation in extent tree
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


This patch addresses a vulnerability in EXT4 extent tree validation
where logically impossible extent entries could be created. The fix
prevents extent entries with an end block less than the start block.

Key changes:
- Add boundary checks to validate extent entries
- Prevent creation of extents with invalid block ranges
- Improve extent tree integrity checks

The bug was discovered via syzkaller, which generated a test case
exposing this boundary condition vulnerability during filesystem
metadata parsing.

Fixes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Reported-by: syzkaller <syzkaller@googlegroups.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 fs/ext4/extents.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca5499e9412b..987a07a8554e 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -418,6 +418,10 @@ static int ext4_valid_extent_entries(struct inode *inode,
 
 			/* Check for overlapping extents */
 			lblock = le32_to_cpu(ext->ee_block);
+			ext4_lblk_t len = ext4_ext_get_actual_len(ext);
+			ext4_lblk_t end = lblock + len - 1;
+			if (end < lblock)
+				return 0;
 			if (lblock < cur) {
 				*pblk = ext4_ext_pblock(ext);
 				return 0;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250928074511.6263-1-kartikey406@gmail.com>
@ 2025-09-28  8:00 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  8:00 UTC (permalink / raw)
  To: kartikey406, linux-kernel, syzkaller-bugs, syzkaller

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
kernel BUG in ext4_es_cache_extent

EXT4-fs (loop0): 1 truncate cleaned up
EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: none.
------------[ cut here ]------------
kernel BUG at fs/ext4/extents_status.c:1012!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 5828 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
RIP: 0010:ext4_es_cache_extent+0x698/0x700 fs/ext4/extents_status.c:1012
Code: ff df 80 3c 08 00 74 08 48 89 df e8 c2 a7 b3 ff 48 8b 3b 48 8b 74 24 28 48 8d 54 24 60 e8 00 c3 0d 00 eb 14 e8 89 ab 4e ff 90 <0f> 0b e8 81 ab 4e ff eb 28 e8 7a ab 4e ff 31 f6 65 ff 0d 01 71 50
RSP: 0018:ffffc90002bcf420 EFLAGS: 00010293
RAX: ffffffff82711f17 RBX: 00000000ffffffff RCX: ffff888033530000
RDX: 0000000000000000 RSI: 00000000ffffffff RDI: 00000000000052ce
RBP: ffffc90002bcf528 R08: ffffffff8fc3c837 R09: 1ffffffff1f87906
R10: dffffc0000000000 R11: fffffbfff1f87907 R12: 00000000000052d0
R13: 0000000000000004 R14: 00000000000052ce R15: dffffc0000000000
FS:  00007fa99e5616c0(0000) GS:ffff88808d007000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2d130e10a0 CR3: 0000000042911000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 ext4_cache_extents fs/ext4/extents.c:548 [inline]
 ext4_find_extent+0x482/0xcc0 fs/ext4/extents.c:932
 ext4_get_verity_descriptor_location fs/ext4/verity.c:292 [inline]
 ext4_get_verity_descriptor+0x102/0x590 fs/ext4/verity.c:346
 fsverity_get_descriptor+0x90/0x4b0 fs/verity/open.c:323
 ensure_verity_info fs/verity/open.c:363 [inline]
 __fsverity_file_open+0xd7/0x1f0 fs/verity/open.c:384
 fsverity_file_open include/linux/fsverity.h:300 [inline]
 ext4_file_open+0x32d/0xa40 fs/ext4/file.c:909
 do_dentry_open+0x950/0x13f0 fs/open.c:965
 vfs_open+0x3b/0x340 fs/open.c:1095
 do_open fs/namei.c:3887 [inline]
 path_openat+0x2ee5/0x3830 fs/namei.c:4046
 do_filp_open+0x1fa/0x410 fs/namei.c:4073
 do_sys_openat2+0x121/0x1c0 fs/open.c:1435
 do_sys_open fs/open.c:1450 [inline]
 __do_sys_openat fs/open.c:1466 [inline]
 __se_sys_openat fs/open.c:1461 [inline]
 __x64_sys_openat+0x138/0x170 fs/open.c:1461
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa99d78ebe9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fa99e561038 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007fa99d9c5fa0 RCX: 00007fa99d78ebe9
RDX: 0000000000000000 RSI: 0000200000000100 RDI: ffffffffffffff9c
RBP: 00007fa99d811e19 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fa99d9c6038 R14: 00007fa99d9c5fa0 R15: 00007ffcadbf0f68
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:ext4_es_cache_extent+0x698/0x700 fs/ext4/extents_status.c:1012
Code: ff df 80 3c 08 00 74 08 48 89 df e8 c2 a7 b3 ff 48 8b 3b 48 8b 74 24 28 48 8d 54 24 60 e8 00 c3 0d 00 eb 14 e8 89 ab 4e ff 90 <0f> 0b e8 81 ab 4e ff eb 28 e8 7a ab 4e ff 31 f6 65 ff 0d 01 71 50
RSP: 0018:ffffc90002bcf420 EFLAGS: 00010293
RAX: ffffffff82711f17 RBX: 00000000ffffffff RCX: ffff888033530000
RDX: 0000000000000000 RSI: 00000000ffffffff RDI: 00000000000052ce
RBP: ffffc90002bcf528 R08: ffffffff8fc3c837 R09: 1ffffffff1f87906
R10: dffffc0000000000 R11: fffffbfff1f87907 R12: 00000000000052d0
R13: 0000000000000004 R14: 00000000000052ce R15: dffffc0000000000
FS:  00007fa99e5616c0(0000) GS:ffff88808d007000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffc8e551f4c CR3: 0000000042911000 CR4: 0000000000352ef0


Tested on:

commit:         51a24b7d Merge tag 'trace-tools-v6.17-rc5' of git://gi..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=114f72e2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=bf99f2510ef92ba5
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=138cfd34580000


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
  2025-09-28  7:45 ` Forwarded: [PATCH] ext4: Fix extent boundary validation in extent tree syzbot
  2025-09-28  9:11 ` Forwarded: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents syzbot
@ 2025-09-28  9:11 ` syzbot
  2025-09-28  9:41 ` Forwarded: [PATCH] ext4: validate extent entries before caching in ext4_find_extent() syzbot
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  9:11 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


syzbot reported a BUG_ON in ext4_es_cache_extent() triggered when
opening a verity file on a corrupted ext4 filesystem mounted without
a journal.

The issue occurs when the extent tree contains out-of-order extents,
which can happen in a corrupted filesystem. In ext4_cache_extents(),
when processing an extent that has a lower logical block number than
the previous extent's end, the calculation of the hole size underflows:

  If prev = 4352 and lblk = 1280:
  lblk - prev = 1280 - 4352 = -3072 (as signed)
  = 4294964224 (as unsigned)

This underflowed value is passed as 'len' to ext4_es_cache_extent(),
where the end block calculation overflows:

  end = lblk + len - 1 = 4352 + 4294964224 - 1 = 1279

Then the BUG_ON(end < lblk) triggers because 1279 < 4352.

Fix this by adding a check in ext4_cache_extents() to ensure extents
are properly ordered before attempting to cache holes. If out-of-order
extents are detected, report the filesystem corruption and return.

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Fixes: a86c6181109a ("ext4: cache extent hole in extent status tree for ext4_da_map_blocks()")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
---
 fs/ext4/extents.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca5499e9412b..2e630b500a31 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -535,10 +535,17 @@ static void ext4_cache_extents(struct inode *inode,
 		ext4_lblk_t lblk = le32_to_cpu(ex->ee_block);
 		int len = ext4_ext_get_actual_len(ex);
 
-		if (prev && (prev != lblk))
-			ext4_es_cache_extent(inode, prev, lblk - prev, ~0,
-					     EXTENT_STATUS_HOLE);
-
+		if (prev && (prev != lblk)) {
+			if (lblk > prev) {
+				ext4_es_cache_extent(inode, prev, lblk - prev, ~0,
+				     EXTENT_STATUS_HOLE);
+			} else {
+				/* Extents out of order - corrupted? */
+				EXT4_ERROR_INODE(inode, "corrupted extent tree: lblk %u < prev %u",
+					 lblk, prev);
+				return;
+			}
+		}
 		if (ext4_ext_is_unwritten(ex))
 			status = EXTENT_STATUS_UNWRITTEN;
 		ext4_es_cache_extent(inode, lblk, len,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
  2025-09-28  7:45 ` Forwarded: [PATCH] ext4: Fix extent boundary validation in extent tree syzbot
@ 2025-09-28  9:11 ` syzbot
  2025-09-28  9:11 ` syzbot
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  9:11 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


syzbot reported a BUG_ON in ext4_es_cache_extent() triggered when
opening a verity file on a corrupted ext4 filesystem mounted without
a journal.

The issue occurs when the extent tree contains out-of-order extents,
which can happen in a corrupted filesystem. In ext4_cache_extents(),
when processing an extent that has a lower logical block number than
the previous extent's end, the calculation of the hole size underflows:

  If prev = 4352 and lblk = 1280:
  lblk - prev = 1280 - 4352 = -3072 (as signed)
  = 4294964224 (as unsigned)

This underflowed value is passed as 'len' to ext4_es_cache_extent(),
where the end block calculation overflows:

  end = lblk + len - 1 = 4352 + 4294964224 - 1 = 1279

Then the BUG_ON(end < lblk) triggers because 1279 < 4352.

Fix this by adding a check in ext4_cache_extents() to ensure extents
are properly ordered before attempting to cache holes. If out-of-order
extents are detected, report the filesystem corruption and return.

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Fixes: a86c6181109a ("ext4: cache extent hole in extent status tree for ext4_da_map_blocks()")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
---
 fs/ext4/extents.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca5499e9412b..2e630b500a31 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -535,10 +535,17 @@ static void ext4_cache_extents(struct inode *inode,
 		ext4_lblk_t lblk = le32_to_cpu(ex->ee_block);
 		int len = ext4_ext_get_actual_len(ex);
 
-		if (prev && (prev != lblk))
-			ext4_es_cache_extent(inode, prev, lblk - prev, ~0,
-					     EXTENT_STATUS_HOLE);
-
+		if (prev && (prev != lblk)) {
+			if (lblk > prev) {
+				ext4_es_cache_extent(inode, prev, lblk - prev, ~0,
+				     EXTENT_STATUS_HOLE);
+			} else {
+				/* Extents out of order - corrupted? */
+				EXT4_ERROR_INODE(inode, "corrupted extent tree: lblk %u < prev %u",
+					 lblk, prev);
+				return;
+			}
+		}
 		if (ext4_ext_is_unwritten(ex))
 			status = EXTENT_STATUS_UNWRITTEN;
 		ext4_es_cache_extent(inode, lblk, len,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250928091137.9626-1-kartikey406@gmail.com>
@ 2025-09-28  9:26 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  9:26 UTC (permalink / raw)
  To: =syzbot, kartikey406, linux-kernel, syzkaller-bugs

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: use-after-free Read in ext4_find_extent

EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: none.
EXT4-fs error (device loop0): ext4_cache_extents:545: inode #15: comm syz.0.17: corrupted extent tree: lblk 0 < prev 66
==================================================================
BUG: KASAN: use-after-free in ext4_ext_binsearch fs/ext4/extents.c:848 [inline]
BUG: KASAN: use-after-free in ext4_find_extent+0x85c/0xa20 fs/ext4/extents.c:963
Read of size 4 at addr ffff888041c23e48 by task syz.0.17/5858

CPU: 0 UID: 0 PID: 5858 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0xca/0x240 mm/kasan/report.c:482
 kasan_report+0x118/0x150 mm/kasan/report.c:595
 ext4_ext_binsearch fs/ext4/extents.c:848 [inline]
 ext4_find_extent+0x85c/0xa20 fs/ext4/extents.c:963
 ext4_get_verity_descriptor_location fs/ext4/verity.c:292 [inline]
 ext4_get_verity_descriptor+0x102/0x590 fs/ext4/verity.c:346
 fsverity_get_descriptor+0x90/0x4b0 fs/verity/open.c:323
 ensure_verity_info fs/verity/open.c:363 [inline]
 __fsverity_file_open+0xd7/0x1f0 fs/verity/open.c:384
 fsverity_file_open include/linux/fsverity.h:300 [inline]
 ext4_file_open+0x32d/0xa40 fs/ext4/file.c:909
 do_dentry_open+0x950/0x13f0 fs/open.c:965
 vfs_open+0x3b/0x340 fs/open.c:1095
 do_open fs/namei.c:3887 [inline]
 path_openat+0x2ee5/0x3830 fs/namei.c:4046
 do_filp_open+0x1fa/0x410 fs/namei.c:4073
 do_sys_openat2+0x121/0x1c0 fs/open.c:1435
 do_sys_open fs/open.c:1450 [inline]
 __do_sys_openat fs/open.c:1466 [inline]
 __se_sys_openat fs/open.c:1461 [inline]
 __x64_sys_openat+0x138/0x170 fs/open.c:1461
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f6cf3b8ebe9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f6cf4aaa038 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007f6cf3dc5fa0 RCX: 00007f6cf3b8ebe9
RDX: 0000000000000000 RSI: 0000200000000100 RDI: ffffffffffffff9c
RBP: 00007f6cf3c11e19 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f6cf3dc6038 R14: 00007f6cf3dc5fa0 R15: 00007fff26487178
 </TASK>

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x55b5a552d pfn:0x41c23
flags: 0x4fff00000000000(node=1|zone=1|lastcpupid=0x7ff)
raw: 04fff00000000000 ffffea0001070948 ffffea0001070888 0000000000000000
raw: 000000055b5a552d 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as freed
page last allocated via order 0, migratetype Movable, gfp_mask 0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), pid 5236, tgid 5236 (dhcpcd), ts 65849526604, free_ts 140329459250
 set_page_owner include/linux/page_owner.h:32 [inline]
 post_alloc_hook+0x240/0x2a0 mm/page_alloc.c:1851
 compaction_alloc_noprof mm/compaction.c:1836 [inline]
 compaction_alloc+0x3099/0x34a0 mm/compaction.c:1847
 migrate_folio_unmap mm/migrate.c:1211 [inline]
 migrate_pages_batch+0x7e2/0x35c0 mm/migrate.c:1873
 migrate_pages_sync mm/migrate.c:1996 [inline]
 migrate_pages+0x1bcc/0x2930 mm/migrate.c:2105
 compact_zone+0x23e1/0x4ab0 mm/compaction.c:2647
 compact_node+0x1d2/0x280 mm/compaction.c:2916
 kcompactd+0xbc8/0x1290 mm/compaction.c:3214
 kthread+0x711/0x8a0 kernel/kthread.c:463
 ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
page last free pid 30 tgid 30 stack trace:
 reset_page_owner include/linux/page_owner.h:25 [inline]
 free_pages_prepare mm/page_alloc.c:1395 [inline]
 __free_frozen_pages+0xbc4/0xd30 mm/page_alloc.c:2895
 __folio_put+0x21b/0x2c0 mm/swap.c:112
 migrate_folio_move mm/migrate.c:1409 [inline]
 migrate_folios_move mm/migrate.c:1719 [inline]
 migrate_pages_batch+0x227f/0x35c0 mm/migrate.c:1966
 migrate_pages_sync mm/migrate.c:1996 [inline]
 migrate_pages+0x1bcc/0x2930 mm/migrate.c:2105
 compact_zone+0x23e1/0x4ab0 mm/compaction.c:2647
 compact_node+0x1d2/0x280 mm/compaction.c:2916
 kcompactd+0xbc8/0x1290 mm/compaction.c:3214
 kthread+0x711/0x8a0 kernel/kthread.c:463
 ret_from_fork+0x439/0x7d0 arch/x86/kernel/process.c:148
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Memory state around the buggy address:
 ffff888041c23d00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff888041c23d80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff888041c23e00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                                              ^
 ffff888041c23e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff888041c23f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================


Tested on:

commit:         51a24b7d Merge tag 'trace-tools-v6.17-rc5' of git://gi..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=15d8f2e2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=bf99f2510ef92ba5
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=15ec3f12580000


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH] ext4: validate extent entries before caching in ext4_find_extent()
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
                   ` (2 preceding siblings ...)
  2025-09-28  9:11 ` syzbot
@ 2025-09-28  9:41 ` syzbot
  2025-09-28  9:41 ` syzbot
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  9:41 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] ext4: validate extent entries before caching in ext4_find_extent()
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


syzbot reported a BUG_ON in ext4_es_cache_extent() triggered when
opening a verity file on a corrupted ext4 filesystem mounted without
a journal.

The issue occurs when the extent tree contains out-of-order extents,
which can happen in a corrupted filesystem. ext4_find_extent() calls
ext4_cache_extents() without validating the extent entries when the
tree depth is 0 (leaf level). This allows corrupted extent trees with
out-of-order extents to be cached, triggering a BUG_ON in
ext4_es_cache_extent() due to integer underflow when calculating hole
sizes:

  If prev = 4352 and lblk = 1280:
  lblk - prev = 1280 - 4352 = -3072 (as signed)
  = 4294964224 (as unsigned)
  end = lblk + len - 1 = 4352 + 4294964224 - 1 = 1279 (after overflow)
  BUG_ON(end < lblk) triggers because 1279 < 4352

Fix this by adding extent entry validation using the existing
ext4_valid_extent_entries() function before caching. This ensures
corrupted extent trees are detected and handled properly through the
error path, preventing both the BUG_ON and potential use-after-free
issues.

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Fixes: a86c6181109a ("ext4: cache extent hole in extent status tree for ext4_da_map_blocks()")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 fs/ext4/extents.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca5499e9412b..f8e45623f7ea 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -924,8 +924,18 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
 	path[0].p_bh = NULL;
 
 	i = depth;
-	if (!(flags & EXT4_EX_NOCACHE) && depth == 0)
+	if (!(flags & EXT4_EX_NOCACHE) && depth == 0) {
+		ext4_fsblk_t pblk = 0;
+
+		if (!ext4_valid_extent_entries(inode, eh, 0, &pblk, 0)) {
+			EXT4_ERROR_INODE(inode,
+				"invalid extent entries, pblk %llu",
+				pblk);
+			ret = -EFSCORRUPTED;
+			goto err;
+		}
 		ext4_cache_extents(inode, eh);
+	}
 	/* walk through the tree */
 	while (i) {
 		ext_debug(inode, "depth %d: num %d, max %d\n",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH] ext4: validate extent entries before caching in ext4_find_extent()
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
                   ` (3 preceding siblings ...)
  2025-09-28  9:41 ` Forwarded: [PATCH] ext4: validate extent entries before caching in ext4_find_extent() syzbot
@ 2025-09-28  9:41 ` syzbot
  2025-09-29 14:40 ` Forwarded: [PATCH v2] ext4: detect invalid INLINE_DATA + EXTENTS flag combination syzbot
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28  9:41 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] ext4: validate extent entries before caching in ext4_find_extent()
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


syzbot reported a BUG_ON in ext4_es_cache_extent() triggered when
opening a verity file on a corrupted ext4 filesystem mounted without
a journal.

The issue occurs when the extent tree contains out-of-order extents,
which can happen in a corrupted filesystem. ext4_find_extent() calls
ext4_cache_extents() without validating the extent entries when the
tree depth is 0 (leaf level). This allows corrupted extent trees with
out-of-order extents to be cached, triggering a BUG_ON in
ext4_es_cache_extent() due to integer underflow when calculating hole
sizes:

  If prev = 4352 and lblk = 1280:
  lblk - prev = 1280 - 4352 = -3072 (as signed)
  = 4294964224 (as unsigned)
  end = lblk + len - 1 = 4352 + 4294964224 - 1 = 1279 (after overflow)
  BUG_ON(end < lblk) triggers because 1279 < 4352

Fix this by adding extent entry validation using the existing
ext4_valid_extent_entries() function before caching. This ensures
corrupted extent trees are detected and handled properly through the
error path, preventing both the BUG_ON and potential use-after-free
issues.

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Fixes: a86c6181109a ("ext4: cache extent hole in extent status tree for ext4_da_map_blocks()")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 fs/ext4/extents.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca5499e9412b..f8e45623f7ea 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -924,8 +924,18 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
 	path[0].p_bh = NULL;
 
 	i = depth;
-	if (!(flags & EXT4_EX_NOCACHE) && depth == 0)
+	if (!(flags & EXT4_EX_NOCACHE) && depth == 0) {
+		ext4_fsblk_t pblk = 0;
+
+		if (!ext4_valid_extent_entries(inode, eh, 0, &pblk, 0)) {
+			EXT4_ERROR_INODE(inode,
+				"invalid extent entries, pblk %llu",
+				pblk);
+			ret = -EFSCORRUPTED;
+			goto err;
+		}
 		ext4_cache_extents(inode, eh);
+	}
 	/* walk through the tree */
 	while (i) {
 		ext_debug(inode, "depth %d: num %d, max %d\n",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250928094135.11584-1-kartikey406@gmail.com>
@ 2025-09-28 10:02 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-28 10:02 UTC (permalink / raw)
  To: =syzbot, kartikey406, linux-kernel, syzkaller-bugs

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com

Tested on:

commit:         51a24b7d Merge tag 'trace-tools-v6.17-rc5' of git://gi..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=10a04ae2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=bf99f2510ef92ba5
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=17df8ae2580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH v2] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
                   ` (4 preceding siblings ...)
  2025-09-28  9:41 ` syzbot
@ 2025-09-29 14:40 ` syzbot
  2025-09-30  9:16 ` Forwarded: [PATCH v3] " syzbot
  2025-09-30 10:45 ` Forwarded: [PATCH v4] " syzbot
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-29 14:40 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH v2] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

syzbot reported a BUG_ON in ext4_es_cache_extent() when opening a verity
file on a corrupted ext4 filesystem mounted without a journal.

The issue is that the filesystem has an inode with both the INLINE_DATA
and EXTENTS flags set:

    EXT4-fs error (device loop0): ext4_cache_extents:545: inode #15:
    comm syz.0.17: corrupted extent tree: lblk 0 < prev 66

Investigation revealed that the inode has both flags set:
    DEBUG: inode 15 - flag=1, i_inline_off=164, has_inline=1

This is an invalid combination since an inode should have either:
- INLINE_DATA: data stored directly in the inode
- EXTENTS: data stored in extent-mapped blocks

Having both flags causes ext4_has_inline_data() to return true, skipping
extent tree validation in __ext4_iget(). The unvalidated out-of-order
extents then trigger a BUG_ON in ext4_es_cache_extent() due to integer
underflow when calculating hole sizes.

Fix this by detecting this invalid flag combination early in ext4_iget()
and rejecting the corrupted inode.

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Suggested-by: Zhang Yi <yi.zhang@huawei.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
Changes in v2:
- Instead of adding validation in ext4_find_extent(), detect the invalid
  INLINE_DATA + EXTENTS flag combination in ext4_iget() as suggested by
  Zhang Yi to avoid redundant checks in the extent lookup path

 fs/ext4/inode.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5b7a15db4953..71fa3faa1475 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5445,6 +5445,15 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
 	}
 
 	ret = 0;
+	/* Detect invalid flag combination - can't have both inline data and extents */
+	if (ext4_test_inode_flag(inode, EXT4_INODE_INLINE_DATA) &&
+		ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
+		ext4_error_inode(inode, __func__, __LINE__, 0,
+			"inode has both inline data and extents flags");
+		ret = -EFSCORRUPTED;
+		goto bad_inode;
+	}
+
 	if (ei->i_file_acl &&
 	    !ext4_inode_block_valid(inode, ei->i_file_acl, 1)) {
 		ext4_error_inode(inode, function, line, 0,
-- 
2.43.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250929144049.359092-1-kartikey406@gmail.com>
@ 2025-09-29 15:01 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-29 15:01 UTC (permalink / raw)
  To: kartikey406, linux-kernel, syzkaller-bugs, yi.zhang

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com

Tested on:

commit:         e5f0a698 Linux 6.17
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=12e426e2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=bf99f2510ef92ba5
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=1755fae2580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH v3] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
                   ` (5 preceding siblings ...)
  2025-09-29 14:40 ` Forwarded: [PATCH v2] ext4: detect invalid INLINE_DATA + EXTENTS flag combination syzbot
@ 2025-09-30  9:16 ` syzbot
  2025-09-30 10:45 ` Forwarded: [PATCH v4] " syzbot
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-30  9:16 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH v3] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

syzbot reported a BUG_ON in ext4_es_cache_extent() when opening a verity
file on a corrupted ext4 filesystem mounted without a journal.

The issue is that the filesystem has an inode with both the INLINE_DATA
and EXTENTS flags set:

    EXT4-fs error (device loop0): ext4_cache_extents:545: inode #15:
    comm syz.0.17: corrupted extent tree: lblk 0 < prev 66

Investigation revealed that the inode has both flags set:
    DEBUG: inode 15 - flag=1, i_inline_off=164, has_inline=1, extents_flag=1

This is an invalid combination since an inode should have either:
- INLINE_DATA: data stored directly in the inode
- EXTENTS: data stored in extent-mapped blocks

Having both flags causes ext4_has_inline_data() to return true, skipping
extent tree validation in __ext4_iget(). The unvalidated out-of-order
extents then trigger a BUG_ON in ext4_es_cache_extent() due to integer
underflow when calculating hole sizes.

Fix this by detecting this invalid flag combination early in ext4_iget()
and rejecting the corrupted inode.

Reported-and-tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Suggested-by: Zhang Yi <yi.zhang@huawei.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
Changes in v3:
- Fix code alignment and use existing function/line variables per Zhang Yi
- Keep check after ret = 0 where all inode fields are initialized, as
  i_inline_off gets set during inode initialization after ext4_set_inode_flags()

Changes in v2:
- Instead of adding validation in ext4_find_extent(), detect the invalid
  INLINE_DATA + EXTENTS flag combination in ext4_iget() as suggested by
  Zhang Yi to avoid redundant checks in the extent lookup path
---
 fs/ext4/inode.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5b7a15db4953..5c97de5775c7 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5445,6 +5445,15 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
 	}
 
 	ret = 0;
+	/* Detect invalid flag combination - can't have both inline data and extents */
+	if (ext4_test_inode_flag(inode, EXT4_INODE_INLINE_DATA) &&
+	    ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
+		ext4_error_inode(inode, function, line, 0,
+			"inode has both inline data and extents flags");
+		ret = -EFSCORRUPTED;
+		goto bad_inode;
+	}
+
 	if (ei->i_file_acl &&
 	    !ext4_inode_block_valid(inode, ei->i_file_acl, 1)) {
 		ext4_error_inode(inode, function, line, 0,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250930091631.310211-1-kartikey406@gmail.com>
@ 2025-09-30  9:37 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-30  9:37 UTC (permalink / raw)
  To: kartikey406, linux-kernel, syzkaller-bugs, yi.zhang

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com

Tested on:

commit:         30d4efb2 Merge tag 'for-linus-6.18-rc1-tag' of git://g..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=16b3f27c580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=607d55e4510cba63
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=13cb16e2580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Forwarded: [PATCH v4] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
  2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
                   ` (6 preceding siblings ...)
  2025-09-30  9:16 ` Forwarded: [PATCH v3] " syzbot
@ 2025-09-30 10:45 ` syzbot
  7 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-30 10:45 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH v4] ext4: detect invalid INLINE_DATA + EXTENTS flag combination
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

syzbot reported a BUG_ON in ext4_es_cache_extent() when opening a verity
file on a corrupted ext4 filesystem mounted without a journal.

The issue is that the filesystem has an inode with both the INLINE_DATA
and EXTENTS flags set:

    EXT4-fs error (device loop0): ext4_cache_extents:545: inode #15:
    comm syz.0.17: corrupted extent tree: lblk 0 < prev 66

Investigation revealed that the inode has both flags set:
    DEBUG: inode 15 - flag=1, i_inline_off=164, has_inline=1, extents_flag=1

This is an invalid combination since an inode should have either:
- INLINE_DATA: data stored directly in the inode
- EXTENTS: data stored in extent-mapped blocks

Having both flags causes ext4_has_inline_data() to return true, skipping
extent tree validation in __ext4_iget(). The unvalidated out-of-order
extents then trigger a BUG_ON in ext4_es_cache_extent() due to integer
underflow when calculating hole sizes.

Fix this by detecting this invalid flag combination early in ext4_iget()
and rejecting the corrupted inode.

Reported-and-tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
Suggested-by: Zhang Yi <yi.zhang@huawei.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>

---
Changes in v4:
- Move check to right after ext4_set_inode_flags() as suggested by Zhang Yi,
  since we're checking flags directly (not ext4_has_inline_data() return value)

Changes in v3:
- Fix code alignment and use existing function/line variables per Zhang Yi

Changes in v2:
- Instead of adding validation in ext4_find_extent(), detect the invalid
  INLINE_DATA + EXTENTS flag combination in ext4_iget() as suggested by
  Zhang Yi to avoid redundant checks in the extent lookup path
---
 fs/ext4/inode.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5b7a15db4953..2fef378dbc97 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5348,6 +5348,14 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
 	}
 	ei->i_flags = le32_to_cpu(raw_inode->i_flags);
 	ext4_set_inode_flags(inode, true);
+	/* Detect invalid flag combination - can't have both inline data and extents */
+	if (ext4_test_inode_flag(inode, EXT4_INODE_INLINE_DATA) &&
+	    ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
+		ext4_error_inode(inode, function, line, 0,
+			"inode has both inline data and extents flags");
+		ret = -EFSCORRUPTED;
+		goto bad_inode;
+	}
 	inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
 	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
 	if (ext4_has_feature_64bit(sb))
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3)
       [not found] <20250930104454.313735-1-kartikey406@gmail.com>
@ 2025-09-30 11:22 ` syzbot
  0 siblings, 0 replies; 15+ messages in thread
From: syzbot @ 2025-09-30 11:22 UTC (permalink / raw)
  To: kartikey406, linux-kernel, syzkaller-bugs, yi.zhang

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com
Tested-by: syzbot+038b7bf43423e132b308@syzkaller.appspotmail.com

Tested on:

commit:         30d4efb2 Merge tag 'for-linus-6.18-rc1-tag' of git://g..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=155b05cd980000
kernel config:  https://syzkaller.appspot.com/x/.config?x=607d55e4510cba63
dashboard link: https://syzkaller.appspot.com/bug?extid=038b7bf43423e132b308
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
patch:          https://syzkaller.appspot.com/x/patch.diff?x=14bbf27c580000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-09-30 11:22 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-04  9:44 [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
2025-09-28  7:45 ` Forwarded: [PATCH] ext4: Fix extent boundary validation in extent tree syzbot
2025-09-28  9:11 ` Forwarded: [PATCH] ext4: fix BUG_ON in ext4_es_cache_extent due to out-of-order extents syzbot
2025-09-28  9:11 ` syzbot
2025-09-28  9:41 ` Forwarded: [PATCH] ext4: validate extent entries before caching in ext4_find_extent() syzbot
2025-09-28  9:41 ` syzbot
2025-09-29 14:40 ` Forwarded: [PATCH v2] ext4: detect invalid INLINE_DATA + EXTENTS flag combination syzbot
2025-09-30  9:16 ` Forwarded: [PATCH v3] " syzbot
2025-09-30 10:45 ` Forwarded: [PATCH v4] " syzbot
     [not found] <20250928074511.6263-1-kartikey406@gmail.com>
2025-09-28  8:00 ` [syzbot] [ext4?] kernel BUG in ext4_es_cache_extent (3) syzbot
     [not found] <20250928091137.9626-1-kartikey406@gmail.com>
2025-09-28  9:26 ` syzbot
     [not found] <20250928094135.11584-1-kartikey406@gmail.com>
2025-09-28 10:02 ` syzbot
     [not found] <20250929144049.359092-1-kartikey406@gmail.com>
2025-09-29 15:01 ` syzbot
     [not found] <20250930091631.310211-1-kartikey406@gmail.com>
2025-09-30  9:37 ` syzbot
     [not found] <20250930104454.313735-1-kartikey406@gmail.com>
2025-09-30 11:22 ` syzbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).