diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2019-01-01 00:11:30 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-10 09:53:45 +0200 |
commit | e2379b044d6742febaea581d2ba6c5d44307cc9f (patch) | |
tree | 50bbff5d2c2840e47e079fd9c1a56c7d5e3019b3 | |
parent | e9fde78c3a4f7f374ffe589771f08e119d0879aa (diff) | |
download | linux-stable-e2379b044d6742febaea581d2ba6c5d44307cc9f.tar.gz |
f2fs: don't access node/meta inode mapping after iput
[ Upstream commit 7c77bf7de1574ac7a31a2b76f4927404307d13e7 ]
This fixes wrong access of address spaces of node and meta inodes after iput.
Fixes: 60aa4d5536ab ("f2fs: fix use-after-free issue when accessing sbi->stat_info")
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | fs/f2fs/debug.c | 19 | ||||
-rw-r--r-- | fs/f2fs/super.c | 5 |
2 files changed, 17 insertions, 7 deletions
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index ebe649d9793cb..bbe155465ca0a 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -94,8 +94,10 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->free_secs = free_sections(sbi); si->prefree_count = prefree_segments(sbi); si->dirty_count = dirty_segments(sbi); - si->node_pages = NODE_MAPPING(sbi)->nrpages; - si->meta_pages = META_MAPPING(sbi)->nrpages; + if (sbi->node_inode) + si->node_pages = NODE_MAPPING(sbi)->nrpages; + if (sbi->meta_inode) + si->meta_pages = META_MAPPING(sbi)->nrpages; si->nats = NM_I(sbi)->nat_cnt; si->dirty_nats = NM_I(sbi)->dirty_nat_cnt; si->sits = MAIN_SEGS(sbi); @@ -168,7 +170,6 @@ static void update_sit_info(struct f2fs_sb_info *sbi) static void update_mem_info(struct f2fs_sb_info *sbi) { struct f2fs_stat_info *si = F2FS_STAT(sbi); - unsigned npages; int i; if (si->base_mem) @@ -251,10 +252,14 @@ get_cache: sizeof(struct extent_node); si->page_mem = 0; - npages = NODE_MAPPING(sbi)->nrpages; - si->page_mem += (unsigned long long)npages << PAGE_SHIFT; - npages = META_MAPPING(sbi)->nrpages; - si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + if (sbi->node_inode) { + unsigned npages = NODE_MAPPING(sbi)->nrpages; + si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + } + if (sbi->meta_inode) { + unsigned npages = META_MAPPING(sbi)->nrpages; + si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + } } static int stat_show(struct seq_file *s, void *v) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2264f27fd26d2..1871031e2d5eb 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1050,7 +1050,10 @@ static void f2fs_put_super(struct super_block *sb) f2fs_bug_on(sbi, sbi->fsync_node_num); iput(sbi->node_inode); + sbi->node_inode = NULL; + iput(sbi->meta_inode); + sbi->meta_inode = NULL; /* * iput() can update stat information, if f2fs_write_checkpoint() @@ -3166,6 +3169,7 @@ free_node_inode: f2fs_release_ino_entry(sbi, true); truncate_inode_pages_final(NODE_MAPPING(sbi)); iput(sbi->node_inode); + sbi->node_inode = NULL; free_stats: f2fs_destroy_stats(sbi); free_nm: @@ -3178,6 +3182,7 @@ free_devices: free_meta_inode: make_bad_inode(sbi->meta_inode); iput(sbi->meta_inode); + sbi->meta_inode = NULL; free_io_dummy: mempool_destroy(sbi->write_io_dummy); free_percpu: |