[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tencent_7C86DFB364837BA979A3B0A44CF768577205@qq.com>
Date: Tue, 15 Oct 2024 12:50:05 +0800
From: Edward Adam Davis <eadavis@...com>
To: guohui.study@...il.com
Cc: brauner@...nel.org,
jack@...e.cz,
jfs-discussion@...ts.sourceforge.net,
linux-kernel@...r.kernel.org,
lizhi.xu@...driver.com,
shaggy@...nel.org,
syzkaller-bugs@...glegroups.com,
willy@...radead.org
Subject: [PATCH] jfs: Fix null-ptr-deref in write_special_inodes
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@...il.com>
Link: https://lore.kernel.org/all/CAHOo4gKf2mjPX8oAxCBUc74=+OToMdu6pe6iALGCOmXjToFaKw@mail.gmail.com/
Signed-off-by: Edward Adam Davis <eadavis@...com>
---
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
Powered by blists - more mailing lists