[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251207065801.2611800-1-kartikey406@gmail.com>
Date: Sun, 7 Dec 2025 12:28:01 +0530
From: Deepanshu Kartikey <kartikey406@...il.com>
To: shaggy@...nel.org,
brauner@...nel.org
Cc: mjguzik@...il.com,
jfs-discussion@...ts.sourceforge.net,
linux-kernel@...r.kernel.org,
Deepanshu Kartikey <kartikey406@...il.com>,
syzbot+a099d674daa27a9272db@...kaller.appspotmail.com
Subject: [PATCH] jfs: fix directory tree corruption in dtSplitRoot()
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.
Fix by resetting dtlck->index to 0 at the grantLock label, but only
for operations with the tlckNEW flag set. This ensures new pages start
with clean state while preserving accumulated changes on existing pages.
Reported-by: syzbot+a099d674daa27a9272db@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a099d674daa27a9272db
Tested-by: Deepanshu Kartikey <kartikey406@...il.com>
Signed-off-by: Deepanshu Kartikey <kartikey406@...il.com>
---
fs/jfs/jfs_txnmgr.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index c16578af3a77..5ce2fc17d967 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -811,6 +811,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
* update tlock vector
*/
grantLock:
+ /*
+ * Reset index for new DTREE locks to ensure clean state.
+ * When locks are reused, index may contain stale values from
+ * previous operations. Operations like dtSplitRoot() expect
+ * index to be 0 when creating new pages (tlckNEW flag).
+ */
+ 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
Powered by blists - more mailing lists