From: David Stevens <[email protected]> In preparation for partially populated kernel stacks, don't assume that vm_area->nr_pages matches THREAD_SIZE when clearing a stack for reuse. Note that the VA range is still THREAD_SIZE in that case but it might not be fully allocated.
Signed-off-by: David Stevens <[email protected]> [Resolve conflict and updated commit msg] Signed-off-by: Mostafa Saleh <[email protected]> --- kernel/fork.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/fork.c b/kernel/fork.c index 2065693e762c..ec4431bf309a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -335,11 +335,16 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) vm_area = alloc_thread_stack_node_from_cache(tsk, node); if (vm_area) { + unsigned long offset = 0; + if (memcg_charge_kernel_stack(vm_area)) { vfree(vm_area->addr); return -ENOMEM; } + if (!IS_ENABLED(CONFIG_STACK_GROWSUP)) + offset = THREAD_SIZE - vm_area->nr_pages * PAGE_SIZE; + /* Reset stack metadata. */ if (!kasan_hw_tags_enabled()) kasan_unpoison_range(vm_area->addr, THREAD_SIZE); @@ -347,7 +352,7 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node) stack = kasan_reset_tag(vm_area->addr); /* Clear stale pointers from reused stack. */ - clear_pages(vm_area->addr, vm_area->nr_pages); + clear_pages(vm_area->addr + offset, vm_area->nr_pages); tsk->stack_vm_area = vm_area; tsk->stack = stack; -- 2.56.0.rc1.315.gc6ed9934b7-goog

