From: Yu Kuai yukuai3@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I78RUK CVE: NA
--------------------------------
Currently nv_init() doesn't handle errors, null-ptr-dereference will be triggered if errors occur.
Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- fs/eulerfs/nvalloc.c | 20 +++++++++++++++++++- fs/eulerfs/nvalloc.h | 2 +- fs/eulerfs/super.c | 8 ++++++-- 3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/fs/eulerfs/nvalloc.c b/fs/eulerfs/nvalloc.c index 8b60a2494636..30e4c75e16e2 100644 --- a/fs/eulerfs/nvalloc.c +++ b/fs/eulerfs/nvalloc.c @@ -525,7 +525,7 @@ void nv_fini(struct super_block *sb) kfree(sbi->gpool); }
-void nv_init(struct super_block *sb, bool init) +int nv_init(struct super_block *sb, bool init) { struct eufs_sb_info *sbi = EUFS_SB(sb); struct mem_pool *ppool; @@ -533,6 +533,9 @@ void nv_init(struct super_block *sb, bool init)
/* allocate pools */ sbi->gpool = kmalloc(sizeof(struct mem_pool), GFP_KERNEL); + if (!sbi->gpool) + return -ENOMEM; + INIT_LIST_HEAD(&sbi->gpool->large_list); INIT_LIST_HEAD(&sbi->gpool->page_list); INIT_LIST_HEAD(&sbi->gpool->line4_list); @@ -543,6 +546,9 @@ void nv_init(struct super_block *sb, bool init) sbi->gpool->nlines = 0;
sbi->rest_pool = kmalloc(sizeof(struct mem_pool), GFP_KERNEL); + if (!sbi->rest_pool) + goto err_rest_pool; + INIT_LIST_HEAD(&sbi->rest_pool->large_list); INIT_LIST_HEAD(&sbi->rest_pool->page_list); INIT_LIST_HEAD(&sbi->rest_pool->line4_list); @@ -554,6 +560,9 @@ void nv_init(struct super_block *sb, bool init) sbi->rest_pool->nlines = 0;
sbi->ppool = alloc_percpu(struct mem_pool); + if (!sbi->ppool) + goto err_ppool; + for_each_online_cpu(cpu) { ppool = per_cpu_ptr(sbi->ppool, cpu); INIT_LIST_HEAD(&ppool->large_list); @@ -568,6 +577,15 @@ void nv_init(struct super_block *sb, bool init) }
partition(sb, init); + return 0; + +err_ppool: + kfree(sbi->rest_pool); + sbi->rest_pool = NULL; +err_rest_pool: + kfree(sbi->gpool); + sbi->gpool = NULL; + return -ENOMEM; }
static int cut_from_list_remaining(struct list_head *head, int remaining, diff --git a/fs/eulerfs/nvalloc.h b/fs/eulerfs/nvalloc.h index a39b81862bfb..17d7d69042c7 100644 --- a/fs/eulerfs/nvalloc.h +++ b/fs/eulerfs/nvalloc.h @@ -134,7 +134,7 @@ int nvmalloc_pre(struct super_block *sb, struct alloc_batch *ab, size_t count, size_t size); void *nvmalloc(struct super_block *sb, size_t size, u8 tag, bool nonblocking); void nvfree(struct super_block *sb, void *ptr, bool rest); -void nv_init(struct super_block *sb, bool init); +int nv_init(struct super_block *sb, bool init); void nv_fini(struct super_block *sb); void eufs_get_layout(struct super_block *sb, bool init);
diff --git a/fs/eulerfs/super.c b/fs/eulerfs/super.c index 43fc717002d7..a4bf568224df 100644 --- a/fs/eulerfs/super.c +++ b/fs/eulerfs/super.c @@ -332,7 +332,9 @@ static struct eufs_inode *eufs_init(struct super_block *sb, unsigned long size) sbi->s_crash_ver = 1; super->s_crash_ver = cpu_to_le64(1);
- nv_init(sb, true); + if (nv_init(sb, true)) + return ERR_PTR(-ENOMEM); + super->s_page_map = cpu_to_le64(p2o(sb, sbi->page_map)); super->s_mtime = 0;
@@ -478,7 +480,9 @@ static int eufs_fill_super(struct super_block *sb, void *data, int silent) eufs_pbarrier(); }
- nv_init(sb, false); + err = nv_init(sb, false); + if (err) + goto out;
root_pi = (struct eufs_inode *)s2p(sb, super->s_root_pi);