hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBGUNQ CVE: NA
--------------------------------
After entering drop_pagecache_sb() during the drop_cache process, the inode reference count is first incremented, then call invalidate_mapping_pages(). One of the parameters passed to this function is inode->i_mapping.
However, if inode->i_mapping holds the i_mapping of another inode, and that other inode has already been released, a UAF issue may occur because the lifecycle of the other inode cannot be guaranteed. This could happen in scenarios such as the bd_acquire->bd_forget process.
By adding relevant filtering conditions to avoid this issue.
Fixes: 9d0243bca345 ("[PATCH] drop-pagecache") Signed-off-by: Zizhi Wo wozizhi@huawei.com --- fs/dirty_pages.c | 4 +++- fs/drop_caches.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/dirty_pages.c b/fs/dirty_pages.c index f75a5158d94b..b2044d78b6f2 100644 --- a/fs/dirty_pages.c +++ b/fs/dirty_pages.c @@ -120,6 +120,7 @@ static void dump_dirtypages_sb(struct super_block *sb, struct seq_file *m)
spin_lock(&sb->s_inode_list_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + nr_dirtys = 0; spin_lock(&inode->i_lock);
/* @@ -138,7 +139,8 @@ static void dump_dirtypages_sb(struct super_block *sb, struct seq_file *m)
cond_resched();
- nr_dirtys = dump_dirtypages_inode(inode); + if (!S_ISBLK(inode->i_mode) || sb_is_blkdev_sb(sb)) + nr_dirtys = dump_dirtypages_inode(inode); if (!nr_dirtys || nr_dirtys < limit) goto skip;
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index f00fcc4a4f72..ded2197a165c 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c @@ -35,7 +35,8 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused) spin_unlock(&inode->i_lock); spin_unlock(&sb->s_inode_list_lock);
- invalidate_mapping_pages(inode->i_mapping, 0, -1); + if (!S_ISBLK(inode->i_mode) || sb_is_blkdev_sb(sb)) + invalidate_mapping_pages(inode->i_mapping, 0, -1); iput(toput_inode); toput_inode = inode;