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);