
From: liubo <liubo254@huawei.com> 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: liubo <liubo254@huawei.com> Reviewed-by: Miaohe Lin <linmiaohe@huawei.com> Reviewed-by: wangkefeng <wangkefeng.wang@huawei.com> Signed-off-by: Laibin Qiu <qiulaibin@huawei.com> --- mm/vmscan.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 011827f666cc..f5671facdc51 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -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); -- 2.25.1