Commit 89ea0cd3 authored by liubo's avatar liubo Committed by Laibin Qiu
Browse files

etmem:fix kernel stack overflow in do_swapcache_reclaim

euleros inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GN7K


CVE: NA

--------------------------------
In the do_swapcache_reclaim interface,
there are the following local variables.

unsigned long nr[MAX_NUMNODES],
unsigned long nr_to_reclaim[MAX_NUMNODES],
struct list_head swapcache_list[MAX_NUMNODES],

In the kernel, MAX_NUMNODES is defined as follows:

Under the x86_64 architecture, CONFIG_NODES_SHIFT is
defined as follows:
CONFIG_NODES_SHIFT=10

Therefore, under the X86_64 architecture, local variables
may cause kernel stack overflow.

Modify the above variable acquisition method
and change it to dynamic application.

Signed-off-by: default avatarliubo <liubo254@huawei.com>
Reviewed-by: default avatarMiaohe Lin <linmiaohe@huawei.com>
Reviewed-by: default avatarwangkefeng <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarLaibin Qiu <qiulaibin@huawei.com>
parent c9a24119
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -4670,12 +4670,12 @@ int do_swapcache_reclaim(unsigned long *swapcache_watermark,
	int err = -EINVAL;
	unsigned long swapcache_to_reclaim = 0;
	unsigned long nr_reclaimed = 0;
	unsigned long nr[MAX_NUMNODES] = {0};
	unsigned long nr_to_reclaim[MAX_NUMNODES] = {0};
	unsigned long swapcache_total_reclaimable = 0;
	unsigned long reclaim_page_count = 0;

	struct list_head swapcache_list[MAX_NUMNODES];
	unsigned long *nr = NULL;
	unsigned long *nr_to_reclaim = NULL;
	struct list_head *swapcache_list = NULL;

	int nid = 0;
	struct lruvec *lruvec = NULL;
@@ -4702,6 +4702,25 @@ int do_swapcache_reclaim(unsigned long *swapcache_watermark,
	if (swapcache_to_reclaim <= 0)
		return err;

	nr = kcalloc(MAX_NUMNODES, sizeof(unsigned long), GFP_KERNEL);
	if (nr == NULL)
		return -ENOMEM;

	nr_to_reclaim = kcalloc(MAX_NUMNODES, sizeof(unsigned long),
				GFP_KERNEL);
	if (nr_to_reclaim == NULL) {
		kfree(nr);
		return -ENOMEM;
	}

	swapcache_list = kcalloc(MAX_NUMNODES, sizeof(struct list_head),
				 GFP_KERNEL);
	if (swapcache_list == NULL) {
		kfree(nr);
		kfree(nr_to_reclaim);
		return -ENOMEM;
	}

	/*
	 * scan the LRU linked list of each memory node to obtain the
	 * swapcache pages that can be reclaimd.
@@ -4829,6 +4848,10 @@ int do_swapcache_reclaim(unsigned long *swapcache_watermark,
		nid_num++;
	}

	kfree(nr);
	kfree(nr_to_reclaim);
	kfree(swapcache_list);

	return 0;
}
EXPORT_SYMBOL_GPL(do_swapcache_reclaim);