[PATCH] jfs: Fix null-ptr-deref in write_special_inodes

From: Edward Adam Davis
Date: Tue Oct 15 2024 - 00:50:29 EST


There is a race condition when accessing ipimap and ipbmap.

CPU1 CPU2
==== ====
jfs_umount
sbi->ipimap = NULL; lmLogSync
sbi->ipbmap = NULL; write_special_inodes
lmLogClose writer(sbi->ipbmap->i_mapping);
writer(sbi->ipimap->i_mapping);

The jfs umount and lmLogSync compete to access ipimap and ipbmap, resulting in
null pointer access to ipimap and ipbmap when executing write_special_inodes.

We can fix it by first closing the log in jfs umount, and then releasing
ipimap/ipbmap.

Reported-by: Hui Guo<guohui.study@xxxxxxxxx>
Link: https://lore.kernel.org/all/CAHOo4gKf2mjPX8oAxCBUc74=+OToMdu6pe6iALGCOmXjToFaKw@xxxxxxxxxxxxxx/
Signed-off-by: Edward Adam Davis <eadavis@xxxxxx>
---
fs/jfs/jfs_umount.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index 8ec43f53f686..c5fda516ca85 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -42,7 +42,7 @@ int jfs_umount(struct super_block *sb)
struct inode *ipaimap = sbi->ipaimap;
struct inode *ipaimap2 = sbi->ipaimap2;
struct jfs_log *log;
- int rc = 0;
+ int rc = 0, sb_update = 0;

jfs_info("UnMount JFS: sb:0x%p", sb);

@@ -51,11 +51,19 @@ int jfs_umount(struct super_block *sb)
*
* if mounted read-write and log based recovery was enabled
*/
- if ((log = sbi->log))
+ if ((log = sbi->log)) {
/*
* Wait for outstanding transactions to be written to log:
*/
jfs_flush_journal(log, 2);
+ /*
+ * close log:
+ *
+ * remove file system from log active file system list.
+ */
+ rc = lmLogClose(sb);
+ sb_update = 1;
+ }

/*
* close fileset inode allocation map (aka fileset inode)
@@ -103,15 +111,8 @@ int jfs_umount(struct super_block *sb)
* consistent state) and log superblock active file system
* list (to signify skip logredo()).
*/
- if (log) { /* log = NULL if read-only mount */
+ if (sb_update) { /* log = NULL if read-only mount */
updateSuper(sb, FM_CLEAN);
-
- /*
- * close log:
- *
- * remove file system from log active file system list.
- */
- rc = lmLogClose(sb);
}
jfs_info("UnMount JFS Complete: rc = %d", rc);
return rc;
--
2.43.0