From: Shaurya Rane ssrane_b23@ee.vjti.ac.in
[ Upstream commit 300b072df72694ea330c4c673c035253e07827b8 ]
The transaction manager initialization in txInit() was not properly initializing TxBlock[0].waitor waitqueue, causing a crash when txEnd(0) is called on read-only filesystems.
When a filesystem is mounted read-only, txBegin() returns tid=0 to indicate no transaction. However, txEnd(0) still gets called and tries to access TxBlock[0].waitor via tid_to_tblock(0), but this waitqueue was never initialized because the initialization loop started at index 1 instead of 0.
This causes a 'non-static key' lockdep warning and system crash: INFO: trying to register non-static key in txEnd
Fix by ensuring all transaction blocks including TxBlock[0] have their waitqueues properly initialized during txInit().
Reported-by: syzbot+c4f3462d8b2ad7977bea@syzkaller.appspotmail.com
Signed-off-by: Shaurya Rane ssrane_b23@ee.vjti.ac.in Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org
LLM Generated explanations, may be completely bogus:
YES
- `txInit()` previously skipped index 0 when priming the `tblock` wait queues, so `TxBlock[0].waitor` stayed uninitialized (`fs/jfs/jfs_txnmgr.c:270-284` before the patch). When the filesystem is mounted read-only, `txBegin()` legitimately returns `tid == 0` (`fs/jfs/jfs_txnmgr.c:348-354`), yet every caller still executes `txEnd(tid)`. `txEnd()` immediately calls `TXN_WAKEUP(&tblk->waitor)` on that reserved entry (`fs/jfs/jfs_txnmgr.c:500-506`), which trips lockdep (“trying to register non-static key”) and can panic the system, exactly as reported by syzbot.
- The fix ensures both `waitor` and `gcwait` are initialized for all `tblock`s, including the reserved slot 0, by running a dedicated loop from 0..nTxBlock-1 before wiring up the freelist (`fs/jfs/jfs_txnmgr.c:275-283`). No other behaviour changes occur: the freelist population for indices ≥1 remains identical, and slot 0 is still excluded from allocation.
- The bug was introduced when `txBegin()` started returning 0 for read- only mounts (commit 95e2b352c03b0a86, already in 6.6+ stable). Thus every supported stable tree that contains that change is susceptible to an immediate kernel crash whenever `txEnd(0)` executes—triggerable by routine metadata operations on a read-only JFS volume.
- The patch is tiny, localized to initialization, and carries negligible regression risk: initializing a waitqueue head twice is safe, and no concurrent activity exists during `txInit()`. There are no prerequisite dependencies.
- Because this resolves a real, user-visible crash introduced in currently-supported stable releases and does so with a minimal, well- scoped change, it squarely meets the stable backport criteria.
fs/jfs/jfs_txnmgr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index be17e3c43582f..7840a03e5bcb7 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -272,14 +272,15 @@ int txInit(void) if (TxBlock == NULL) return -ENOMEM;
- for (k = 1; k < nTxBlock - 1; k++) {
TxBlock[k].next = k + 1;
- for (k = 0; k < nTxBlock; k++) { init_waitqueue_head(&TxBlock[k].gcwait); init_waitqueue_head(&TxBlock[k].waitor); }
- for (k = 1; k < nTxBlock - 1; k++) {
TxBlock[k].next = k + 1;- } TxBlock[k].next = 0;
- init_waitqueue_head(&TxBlock[k].gcwait);
- init_waitqueue_head(&TxBlock[k].waitor);
TxAnchor.freetid = 1; init_waitqueue_head(&TxAnchor.freewait); -- 2.51.0
I see the command but can't find the corresponding bug. The email is sent to syzbot+HASH@syzkaller.appspotmail.com address but the HASH does not correspond to any known bug. Please double check the address.