Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

jfs: hold LOG_LOCK on umount to avoid null-ptr-deref

write_special_inodes() function iterate through the log->sb_list and
access the sbi fields, which can be set to NULL concurrently by umount.

Fix concurrency issue by holding LOG_LOCK and checking for NULL.

Reported-by: syzbot+e14b1036481911ae4d77@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e14b1036481911ae4d77
Signed-off-by: Helen Koike <koike@igalia.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>

authored by

Helen Koike and committed by
Dave Kleikamp
ca5848ae b15e4310

+24 -9
+7 -9
fs/jfs/jfs_logmgr.c
··· 74 74 static DEFINE_SPINLOCK(log_redrive_lock); 75 75 76 76 77 - /* 78 - * log read/write serialization (per log) 79 - */ 80 - #define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock) 81 - #define LOG_LOCK(log) mutex_lock(&((log)->loglock)) 82 - #define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock)) 83 77 84 78 85 79 /* ··· 198 204 struct jfs_sb_info *sbi; 199 205 200 206 list_for_each_entry(sbi, &log->sb_list, log_list) { 201 - writer(sbi->ipbmap->i_mapping); 202 - writer(sbi->ipimap->i_mapping); 203 - writer(sbi->direct_inode->i_mapping); 207 + /* These pointers can be NULL before list_del during umount */ 208 + if (sbi->ipbmap) 209 + writer(sbi->ipbmap->i_mapping); 210 + if (sbi->ipimap) 211 + writer(sbi->ipimap->i_mapping); 212 + if (sbi->direct_inode) 213 + writer(sbi->direct_inode->i_mapping); 204 214 } 205 215 } 206 216
+7
fs/jfs/jfs_logmgr.h
··· 403 403 }; 404 404 405 405 /* 406 + * log read/write serialization (per log) 407 + */ 408 + #define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock) 409 + #define LOG_LOCK(log) mutex_lock(&((log)->loglock)) 410 + #define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock)) 411 + 412 + /* 406 413 * Log flag 407 414 */ 408 415 #define log_INLINELOG 1
+10
fs/jfs/jfs_umount.c
··· 20 20 #include "jfs_superblock.h" 21 21 #include "jfs_dmap.h" 22 22 #include "jfs_imap.h" 23 + #include "jfs_logmgr.h" 23 24 #include "jfs_metapage.h" 24 25 #include "jfs_debug.h" 25 26 ··· 59 58 jfs_flush_journal(log, 2); 60 59 61 60 /* 61 + * Hold log lock so write_special_inodes (lmLogSync) cannot see 62 + * this sbi with a NULL inode pointer while iterating log->sb_list. 63 + */ 64 + if (log) 65 + LOG_LOCK(log); 66 + /* 62 67 * close fileset inode allocation map (aka fileset inode) 63 68 */ 64 69 diUnmount(ipimap, 0); ··· 101 94 * the superblock as clean 102 95 */ 103 96 filemap_write_and_wait(sbi->direct_inode->i_mapping); 97 + 98 + if (log) 99 + LOG_UNLOCK(log); 104 100 105 101 /* 106 102 * ensure all file system file pages are propagated to their