Commit e15e6869 authored by Yu Kuai's avatar Yu Kuai Committed by Jialin Zhang
Browse files

eulerfs: add error handling for nv_init()

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: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent 2eb22263
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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);

+6 −2
Original line number Diff line number Diff line
@@ -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);