From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D8D4C33CAF for ; Thu, 16 Jan 2020 16:57:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A0DD24656 for ; Thu, 16 Jan 2020 16:57:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579193832; bh=8tl6avoclmnYqs2n1VijeIdE5boQXiaiZbXvYV5dn8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=JHQYRTYRKY+0xK9C1B75vBg4VuoiTfF/+pCmt4S8+ORjUAKCN+w0lHu+16UY+/z/z x9HE+kFf4reMIXhAL5xTmoSSKOuEhsIyE7scfVx53iQkvQu8aiVmAVV8wMakRa4g9O hq2gG5M0SuV3HpUPdpPyw5Xf/4zOnblhtiWPQdSk= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387447AbgAPQ5L (ORCPT ); Thu, 16 Jan 2020 11:57:11 -0500 Received: from mail.kernel.org ([198.145.29.99]:43886 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387423AbgAPQ5G (ORCPT ); Thu, 16 Jan 2020 11:57:06 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 30A752467D; Thu, 16 Jan 2020 16:57:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579193825; bh=8tl6avoclmnYqs2n1VijeIdE5boQXiaiZbXvYV5dn8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BUaNaNp6UviBnSe/WcATossOGVTVyHgrhuVNCgXOdjqRDcSkWqP0gPi53CmoFMgPj fBx5NF7S10QtSCDOakYk9CyOsdKEvWSsQKHOmHM+GovcRDmr3SWGyy172DiOcwRbPd 5d6lrGZnP8t/tLWHiThAO6cDRrVQjYWe0ApvaEPU= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Rik van Riel , Roman Gushchin , Michal Hocko , Shakeel Butt , Johannes Weiner , Tejun Heo , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH AUTOSEL 4.19 083/671] fork,memcg: fix crash in free_thread_stack on memcg charge fail Date: Thu, 16 Jan 2020 11:45:14 -0500 Message-Id: <20200116165502.8838-83-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200116165502.8838-1-sashal@kernel.org> References: <20200116165502.8838-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rik van Riel [ Upstream commit 5eed6f1dff87bfb5e545935def3843edf42800f2 ] Commit 9b6f7e163cd0 ("mm: rework memcg kernel stack accounting") will result in fork failing if allocating a kernel stack for a task in dup_task_struct exceeds the kernel memory allowance for that cgroup. Unfortunately, it also results in a crash. This is due to the code jumping to free_stack and calling free_thread_stack when the memcg kernel stack charge fails, but without tsk->stack pointing at the freshly allocated stack. This in turn results in the vfree_atomic in free_thread_stack oopsing with a backtrace like this: #5 [ffffc900244efc88] die at ffffffff8101f0ab #6 [ffffc900244efcb8] do_general_protection at ffffffff8101cb86 #7 [ffffc900244efce0] general_protection at ffffffff818ff082 [exception RIP: llist_add_batch+7] RIP: ffffffff8150d487 RSP: ffffc900244efd98 RFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff88085ef55980 RCX: 0000000000000000 RDX: ffff88085ef55980 RSI: 343834343531203a RDI: 343834343531203a RBP: ffffc900244efd98 R8: 0000000000000001 R9: ffff8808578c3600 R10: 0000000000000000 R11: 0000000000000001 R12: ffff88029f6c21c0 R13: 0000000000000286 R14: ffff880147759b00 R15: 0000000000000000 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #8 [ffffc900244efda0] vfree_atomic at ffffffff811df2c7 #9 [ffffc900244efdb8] copy_process at ffffffff81086e37 #10 [ffffc900244efe98] _do_fork at ffffffff810884e0 #11 [ffffc900244eff10] sys_vfork at ffffffff810887ff #12 [ffffc900244eff20] do_syscall_64 at ffffffff81002a43 RIP: 000000000049b948 RSP: 00007ffcdb307830 RFLAGS: 00000246 RAX: ffffffffffffffda RBX: 0000000000896030 RCX: 000000000049b948 RDX: 0000000000000000 RSI: 00007ffcdb307790 RDI: 00000000005d7421 RBP: 000000000067370f R8: 00007ffcdb3077b0 R9: 000000000001ed00 R10: 0000000000000008 R11: 0000000000000246 R12: 0000000000000040 R13: 000000000000000f R14: 0000000000000000 R15: 000000000088d018 ORIG_RAX: 000000000000003a CS: 0033 SS: 002b The simplest fix is to assign tsk->stack right where it is allocated. Link: http://lkml.kernel.org/r/20181214231726.7ee4843c@imladris.surriel.com Fixes: 9b6f7e163cd0 ("mm: rework memcg kernel stack accounting") Signed-off-by: Rik van Riel Acked-by: Roman Gushchin Acked-by: Michal Hocko Cc: Shakeel Butt Cc: Johannes Weiner Cc: Tejun Heo Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- kernel/fork.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 8cb5cd7c97e1..5718c5decc55 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -230,8 +230,10 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) * free_thread_stack() can be called in interrupt context, * so cache the vm_struct. */ - if (stack) + if (stack) { tsk->stack_vm_area = find_vm_area(stack); + tsk->stack = stack; + } return stack; #else struct page *page = alloc_pages_node(node, THREADINFO_GFP, @@ -268,7 +270,10 @@ static struct kmem_cache *thread_stack_cache; static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) { - return kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node); + unsigned long *stack; + stack = kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node); + tsk->stack = stack; + return stack; } static void free_thread_stack(struct task_struct *tsk) -- 2.20.1