* [syzbot] [jfs?] kernel BUG in dtSplitRoot
@ 2025-12-06 8:38 syzbot
2025-12-07 4:57 ` Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot() syzbot
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: syzbot @ 2025-12-06 8:38 UTC (permalink / raw)
To: jfs-discussion, linux-kernel, shaggy, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 1d18101a644e Merge tag 'kernel-6.19-rc1.cred' of git://git..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=132812b4580000
kernel config: https://syzkaller.appspot.com/x/.config?x=a1db0fea040c2a9f
dashboard link: https://syzkaller.appspot.com/bug?extid=a099d674daa27a9272db
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=14f9e512580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=10add512580000
Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-1d18101a.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/98f78b52cccd/vmlinux-1d18101a.xz
kernel image: https://storage.googleapis.com/syzbot-assets/7a8898061bfb/bzImage-1d18101a.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/1671de9ba119/mount_0.gz
fsck result: failed (log: https://syzkaller.appspot.com/x/fsck.log?x=10f9e512580000)
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+a099d674daa27a9272db@syzkaller.appspotmail.com
UFO tlock:0xffffc9000152d5e8
BUG at fs/jfs/jfs_dtree.c:1942 assert(dtlck->index == 0)
------------[ cut here ]------------
kernel BUG at fs/jfs/jfs_dtree.c:1942!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 5663 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:dtSplitRoot+0x1694/0x16c0 fs/jfs/jfs_dtree.c:1942
Code: e9 49 f3 ff ff e8 2c fc 77 fe 48 c7 c7 e0 88 a4 8b 48 c7 c6 c0 87 a4 8b ba 96 07 00 00 48 c7 c1 60 89 a4 8b e8 3d 01 df fd 90 <0f> 0b e8 05 fc 77 fe 48 c7 c7 e0 88 a4 8b 48 c7 c6 c0 87 a4 8b ba
RSP: 0018:ffffc9000d2972a8 EFLAGS: 00010246
RAX: 0000000000000038 RBX: 0000000000001000 RCX: c529552525a5ed00
RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
RBP: ffffc9000152d6db R08: ffff88801fe24253 R09: 1ffff11003fc484a
R10: dffffc0000000000 R11: ffffed1003fc484b R12: dffffc0000000000
R13: 1ffff920002a5adb R14: 0000000000000002 R15: ffffc9000152d6c0
FS: 0000555582889500(0000) GS:ffff88808d722000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fe1757d0e9c CR3: 000000004fc9e000 CR4: 0000000000352ef0
Call Trace:
<TASK>
dtSplitUp fs/jfs/jfs_dtree.c:1244 [inline]
dtInsert+0x2525/0x5f40 fs/jfs/jfs_dtree.c:871
jfs_create+0x6c8/0xa80 fs/jfs/namei.c:137
lookup_open fs/namei.c:3866 [inline]
open_last_lookups fs/namei.c:3965 [inline]
path_openat+0x188f/0x3b80 fs/namei.c:4201
do_filp_open+0x1fa/0x410 fs/namei.c:4231
do_sys_openat2+0x121/0x1c0 fs/open.c:1437
do_sys_open fs/open.c:1452 [inline]
__do_sys_creat fs/open.c:1530 [inline]
__se_sys_creat fs/open.c:1524 [inline]
__x64_sys_creat+0x8f/0xc0 fs/open.c:1524
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f94e718f7c9
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:00007ffe798e7728 EFLAGS: 00000246 ORIG_RAX: 0000000000000055
RAX: ffffffffffffffda RBX: 00007f94e73e5fa0 RCX: 00007f94e718f7c9
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000200000000580
RBP: 00007f94e7213f91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f94e73e5fa0 R14: 00007f94e73e5fa0 R15: 0000000000000002
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:dtSplitRoot+0x1694/0x16c0 fs/jfs/jfs_dtree.c:1942
Code: e9 49 f3 ff ff e8 2c fc 77 fe 48 c7 c7 e0 88 a4 8b 48 c7 c6 c0 87 a4 8b ba 96 07 00 00 48 c7 c1 60 89 a4 8b e8 3d 01 df fd 90 <0f> 0b e8 05 fc 77 fe 48 c7 c7 e0 88 a4 8b 48 c7 c6 c0 87 a4 8b ba
RSP: 0018:ffffc9000d2972a8 EFLAGS: 00010246
RAX: 0000000000000038 RBX: 0000000000001000 RCX: c529552525a5ed00
RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
RBP: ffffc9000152d6db R08: ffff88801fe24253 R09: 1ffff11003fc484a
R10: dffffc0000000000 R11: ffffed1003fc484b R12: dffffc0000000000
R13: 1ffff920002a5adb R14: 0000000000000002 R15: ffffc9000152d6c0
FS: 0000555582889500(0000) GS:ffff88808d722000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2ca51ff000 CR3: 000000004fc9e000 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] 4+ messages in thread
* Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot()
2025-12-06 8:38 [syzbot] [jfs?] kernel BUG in dtSplitRoot syzbot
@ 2025-12-07 4:57 ` syzbot
2025-12-07 5:21 ` syzbot
2025-12-07 6:05 ` syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2025-12-07 4:57 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] jfs: fix directory tree corruption in dtSplitRoot()
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
When inserting directory entries with long filenames that trigger tree
splits, the kernel crashes with "BUG at fs/jfs/jfs_dtree.c:1942" on the
assertion ASSERT(dtlck->index == 0).
The issue occurs due to improper lock reuse in txLock(). When a
transaction lock is reused (either from the same transaction or
transferred from an anonymous transaction), the dtlck->index field is
not reset, retaining its stale value from previous operations.
dtSplitRoot() expects dtlck->index to be 0 when creating a new root
node, as it needs to log directory entries starting from position 0. A
non-zero index causes entries to be written at incorrect positions,
corrupting the new root node's structure.
Lock allocation paths in txLock():
1. allocateLock path: Correctly initializes linelock->index = 0
2. Lock reuse paths: Jump to grantLock, skipping initialization
This leaves reused locks with stale index values (e.g., index=3 from
a previous operation where 3 entries were logged), causing the
assertion to fail.
Example sequence showing the bug:
- First file creation: fresh lock, index=0 -> success
- Second file creation: reused lock, index=3 -> assertion fails
Fix by unconditionally resetting dtlck->index to 0 in the grantLock
path for all DTREE lock types. This ensures clean state regardless of
whether the lock is freshly allocated or reused, preventing the stale
index from corrupting directory tree operations.
Reproducer triggers the issue with a corrupted JFS filesystem image
followed by multiple file creations with long names (~250 characters)
that force directory tree splits.
Reported-by: syzbot+a099d674daa27a9272db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a099d674daa27a9272db
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
fs/jfs/jfs_txnmgr.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index c16578af3a77..2c0678b03f66 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -811,6 +811,11 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
* update tlock vector
*/
grantLock:
+ if (type & tlckDTREE) {
+ struct dt_lock *dtlck = (struct dt_lock *) &tlck->lock;
+
+ dtlck->index = 0;
+ }
tlck->type |= type;
return tlck;
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot()
2025-12-06 8:38 [syzbot] [jfs?] kernel BUG in dtSplitRoot syzbot
2025-12-07 4:57 ` Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot() syzbot
@ 2025-12-07 5:21 ` syzbot
2025-12-07 6:05 ` syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2025-12-07 5:21 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] jfs: fix directory tree corruption in dtSplitRoot()
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
When inserting directory entries with long filenames that trigger tree
splits, the kernel crashes with "BUG at fs/jfs/jfs_dtree.c:1942" on the
assertion ASSERT(dtlck->index == 0).
The issue occurs due to improper lock reuse in txLock(). When a
transaction lock is reused (either from the same transaction or
transferred from an anonymous transaction), the dtlck->index field is
not reset, retaining its stale value from previous operations.
dtSplitRoot() expects dtlck->index to be 0 when creating a new root
node, as it needs to log directory entries starting from position 0. A
non-zero index causes entries to be written at incorrect positions,
corrupting the new root node's structure.
Lock allocation paths in txLock():
1. allocateLock path: Correctly initializes linelock->index = 0
2. Lock reuse paths: Jump to grantLock, skipping initialization
This leaves reused locks with stale index values (e.g., index=3 from
a previous operation where 3 entries were logged), causing the
assertion to fail.
Example sequence showing the bug:
- First file creation: fresh lock, index=0 -> success
- Second file creation: reused lock, index=3 -> assertion fails
Fix by unconditionally resetting dtlck->index to 0 in the grantLock
path for all DTREE lock types. This ensures clean state regardless of
whether the lock is freshly allocated or reused, preventing the stale
index from corrupting directory tree operations.
Reproducer triggers the issue with a corrupted JFS filesystem image
followed by multiple file creations with long names (~250 characters)
that force directory tree splits.
Reported-by: syzbot+a099d674daa27a9272db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a099d674daa27a9272db
Tested-by: Deepanshu Kartikey <kartikey406@gmail.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
fs/jfs/jfs_txnmgr.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index c16578af3a77..0bb8cf6eb1c0 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -811,6 +811,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
* update tlock vector
*/
grantLock:
+ if ((type & tlckDTREE) && (type & tlckNEW)) {
+ struct dt_lock *dtlck = (struct dt_lock *) &tlck->lock;
+ dtlck->index = 0;
+ }
tlck->type |= type;
return tlck;
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot()
2025-12-06 8:38 [syzbot] [jfs?] kernel BUG in dtSplitRoot syzbot
2025-12-07 4:57 ` Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot() syzbot
2025-12-07 5:21 ` syzbot
@ 2025-12-07 6:05 ` syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2025-12-07 6:05 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] jfs: fix directory tree corruption in dtSplitRoot()
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
When reusing transaction locks for DTREE operations, the index field
may contain stale values from previous operations, causing assertion
failures in dtSplitRoot():
ASSERT(dtlck->index == 0)
This results in kernel crashes like:
kernel BUG at fs/jfs/jfs_dtree.c:1942!
Call Trace:
dtSplitRoot+0x1694/0x16c0 fs/jfs/jfs_dtree.c:1942
dtSplitUp fs/jfs/jfs_dtree.c:1244 [inline]
dtInsert+0x2525/0x5f40 fs/jfs/jfs_dtree.c:871
jfs_create+0x6c8/0xa80 fs/jfs/namei.c:137
The bug occurs because txLock() has multiple code paths for lock
acquisition:
1. Fresh allocation (allocateLock) - correctly initializes index to 0
2. Lock reuse (same transaction) - skips initialization
3. Anonymous lock acquisition - skips initialization
Paths 2 and 3 jump directly to the grantLock label, bypassing the
index initialization. When dtSplitRoot() is called multiple times
within a batched transaction (which JFS uses for performance), it may
receive a reused lock with index=3 from a previous operation instead
of the expected index=0.
Example sequence:
Transaction tid=1:
- First dtSplitRoot: gets fresh lock, index=0 ✓
- Modifies entries, index becomes 3
- Lock returned to pool but not freed
Transaction tid=1 (continues):
- Second dtSplitRoot: reuses same lock
- index still = 3 (stale value) ✗
- ASSERT(index == 0) fails → crash
Fix by resetting dtlck->index to 0 at the grantLock label, but only
for operations with the tlckNEW flag set. This ensures:
- New pages (like dtSplitRoot) start with clean state (index=0)
- Existing pages preserve accumulated changes within a transaction
- No performance impact (only affects new page operations)
The tlckNEW flag is used by dtSplitRoot() when creating a new root
page, making this fix targeted to the exact scenario that requires
index=0.
Reported-by: syzbot+a099d674daa27a9272db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a099d674daa27a9272db
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
fs/jfs/jfs_dtree.c | 8 +++++++-
fs/jfs/jfs_txnmgr.c | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 0ab83bb7bbdf..6e5b4431f287 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -1926,7 +1926,13 @@ static int dtSplitRoot(tid_t tid,
*/
tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
dtlck = (struct dt_lock *) & tlck->lock;
-
+ printk(KERN_ERR "JFS_DEBUG: dtSplitRoot before assertion\n");
+ printk(KERN_ERR " tid=%d, ip=%p, rmp=%p\n", tid, ip, rmp);
+ printk(KERN_ERR " tlck=%p, tlck->tid=%d, tlck->type=0x%x\n", tlck, tlck->tid, tlck->type);
+ printk(KERN_ERR " dtlck=%p, dtlck->index=%d\n", dtlck, dtlck->index);
+ if (dtlck->index != 0) {
+ printk(KERN_ERR " ERROR: index is %d, expected 0!\n", dtlck->index);
+ }
rp->header.flag =
(sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
rp->header.self = *pxd;
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index c16578af3a77..bb2fb9bc3440 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -811,6 +811,23 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
* update tlock vector
*/
grantLock:
+ if ((type & tlckDTREE) && (type & tlckNEW)) {
+ struct dt_lock *dtlck = (struct dt_lock *)&tlck->lock;
+ struct linelock *linelock = (struct linelock *)&tlck->lock;
+ printk(KERN_ERR "JFS_DEBUG: txLock grantLock (DTREE)\n");
+ printk(KERN_ERR " tid=%d, ip=%p, mp=%p\n", tid, ip, mp);
+ printk(KERN_ERR " type=0x%x (DTREE=%d, NEW=%d)\n", type, !!(type & tlckDTREE), !!(type & tlckNEW));
+ printk(KERN_ERR " tlck=%p, tlck->tid=%d\n", tlck, tlck->tid);
+ printk(KERN_ERR " BEFORE: linelock->index=%d\n", linelock->index);
+ printk(KERN_ERR " BEFORE: linelock->next=%d, flag=%d\n",linelock->next, linelock->flag);
+ if (type & tlckNEW) {
+ printk(KERN_ERR " ACTION: Resetting index to 0 (tlckNEW)\n");
+ dtlck->index = 0;
+ } else {
+ printk(KERN_ERR " ACTION: NOT resetting (no tlckNEW)\n");
+ }
+ printk(KERN_ERR " AFTER: linelock->index=%d\n", linelock->index);
+ }
tlck->type |= type;
return tlck;
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-12-07 6:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-06 8:38 [syzbot] [jfs?] kernel BUG in dtSplitRoot syzbot
2025-12-07 4:57 ` Forwarded: [PATCH] jfs: fix directory tree corruption in dtSplitRoot() syzbot
2025-12-07 5:21 ` syzbot
2025-12-07 6:05 ` syzbot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome