Skip to content

Commit 9b5a04a

Browse files
konisakpm00
authored andcommitted
nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode()
During unmount process of nilfs2, nothing holds nilfs_root structure after nilfs2 detaches its writer in nilfs_detach_log_writer(). However, since nilfs_evict_inode() uses nilfs_root for some cleanup operations, it may cause use-after-free read if inodes are left in "garbage_list" and released by nilfs_dispose_list() at the end of nilfs_detach_log_writer(). Fix this issue by modifying nilfs_evict_inode() to only clear inode without additional metadata changes that use nilfs_root if the file system is degraded to read-only or the writer is detached. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ryusuke Konishi <[email protected]> Reported-by: [email protected] Closes: https://lkml.kernel.org/r/[email protected] Tested-by: Ryusuke Konishi <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 04fc781 commit 9b5a04a

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

fs/nilfs2/inode.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ void nilfs_evict_inode(struct inode *inode)
917917
struct nilfs_transaction_info ti;
918918
struct super_block *sb = inode->i_sb;
919919
struct nilfs_inode_info *ii = NILFS_I(inode);
920+
struct the_nilfs *nilfs;
920921
int ret;
921922

922923
if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) {
@@ -929,6 +930,23 @@ void nilfs_evict_inode(struct inode *inode)
929930

930931
truncate_inode_pages_final(&inode->i_data);
931932

933+
nilfs = sb->s_fs_info;
934+
if (unlikely(sb_rdonly(sb) || !nilfs->ns_writer)) {
935+
/*
936+
* If this inode is about to be disposed after the file system
937+
* has been degraded to read-only due to file system corruption
938+
* or after the writer has been detached, do not make any
939+
* changes that cause writes, just clear it.
940+
* Do this check after read-locking ns_segctor_sem by
941+
* nilfs_transaction_begin() in order to avoid a race with
942+
* the writer detach operation.
943+
*/
944+
clear_inode(inode);
945+
nilfs_clear_inode(inode);
946+
nilfs_transaction_abort(sb);
947+
return;
948+
}
949+
932950
/* TODO: some of the following operations may fail. */
933951
nilfs_truncate_bmap(ii, 0);
934952
nilfs_mark_inode_dirty(inode);

0 commit comments

Comments
 (0)