The functions txEnd() and txExit() can be concurrently executed in the following call contexts:
Thread1: jfs_lazycommit() txLazyCommit() txEnd() Thread2: exit_jfs_fs() txExit() In txEnd(): struct tblock *tblk = tid_to_tblock(tid); // #define tid_to_tblock(tid) (&TxBlock[tid]) In txExit(): vfree(TxBlock); TxBlock = NULL; Thus, data races can occur for the global variable TxBlock. And these data races can cause use-after-free bugs and null-pointer dereferences. To fix these data races, txExit() is called after the filesystem stops the threads that run jfs_lazycommit(). These data races are found by our concurrency fuzzer. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- fs/jfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index b2dc4d1f9dcc..8c80397df336 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -1027,13 +1027,13 @@ static void __exit exit_jfs_fs(void) jfs_info("exit_jfs_fs called"); - txExit(); metapage_exit(); kthread_stop(jfsIOthread); for (i = 0; i < commit_threads; i++) kthread_stop(jfsCommitThread[i]); kthread_stop(jfsSyncThread); + txExit(); #ifdef PROC_FS_JFS jfs_proc_clean(); #endif -- 2.17.1