Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp3664730ima; Mon, 4 Feb 2019 03:05:09 -0800 (PST) X-Google-Smtp-Source: ALg8bN5mXmRRiZ/3QZXn0mUHgfrNRg/qt4Lte+od57YxKEFbeiuNWZi+URh5QAlvtvqiCemEwBQS X-Received: by 2002:a17:902:1745:: with SMTP id i63mr49907660pli.145.1549278309036; Mon, 04 Feb 2019 03:05:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549278309; cv=none; d=google.com; s=arc-20160816; b=zMVIhyQowQAzK90HWLXV6kL5oVLI1uhDvaAKD1KcWU7AukVY8STlnXZ9KtbTGb7bC0 sYoqtCQln0kdoSyWzAeIEZqjSAOg3ZMBAk10tWs+UDlr6eTZXkuEgkd8w3dQvD/v6sn8 aPC1rmDM6mybdkBFRPHlToE49RrkijnRvWoJlWoCgORDRQSn5Q/2vFnEP8XneNbATuYC 6FUlRHVP8DZQQrLefLf51/oFth5ZW4c59W7htlezSS/ZDF2o3AWN/26OZV/X9sZ/odau dLTA6Zj6elIkqlLzIxYLEdwDbuN/QC2/ttm+fKk8U9mpAMYpSk1LDq04D8G3zq4BD4pb WdpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qNf6C+Z8hrzuKc/JeVAcCE4KQGMeimzpGxg4LY0WbeE=; b=cDRxTHopVGNn0iFrbIUGmp9og8LRy/dGKmj1wl/zdcDurQkVHP1SHP+lE4AtE2TV0B AhtdYAv5+KRK2xsUH07EW3R6IM2wRw50cse+3dWNbnOYN0PV4BhSJAsfw4SAGOKRRa1P GF/qjO/v1/F6B0c74Vb5qyQcWjXS1ViBxwHgkDwLhmkH6vz9JLrH4x2ovA2IuMgXcpJe fg1HGosCCsm476LGUw71eC7B4r59gKZy14ScQGzgd8YEFEJbnla4n7wDnGZdCF9deUUA rl2+kFLcI2kuXvW3WEj2jAnI7FXGcG5ax6NE87rDGBsrOBO/IC3ScgdZ4Y9V0iw+jPEj 6xsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nFhRsF32; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 3si2230033plo.217.2019.02.04.03.04.52; Mon, 04 Feb 2019 03:05:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nFhRsF32; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731310AbfBDKqC (ORCPT + 99 others); Mon, 4 Feb 2019 05:46:02 -0500 Received: from mail.kernel.org ([198.145.29.99]:44112 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731294AbfBDKp6 (ORCPT ); Mon, 4 Feb 2019 05:45:58 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C6F94217D6; Mon, 4 Feb 2019 10:45:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1549277157; bh=9G2KwPyQxbfJ/EixTu6pRh9GBlvEY9zmIv/aPE10Gqo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nFhRsF32djDsio8/hSCqRr/j2dDw+8RPwxarO0rfC8buNalrRhtpMeyOBvX7g5c9y cV3dcsCLlJcX1vZzLjepqyZ2goFZfwTEXYIUecATkMz4m+OABsKuJICV2PfuTMpaZR C3Iq8VDSJuq6+u3ciltbb02I/asJ5jlkMKOTMDnw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+7fbbfa368521945f0e3d@syzkaller.appspotmail.com, Shakeel Butt , Roman Gushchin , Michal Hocko , David Rientjes , Johannes Weiner , Tetsuo Handa , Andrew Morton , Linus Torvalds Subject: [PATCH 4.14 40/46] mm, oom: fix use-after-free in oom_kill_process Date: Mon, 4 Feb 2019 11:37:11 +0100 Message-Id: <20190204103615.656474440@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190204103608.651205056@linuxfoundation.org> References: <20190204103608.651205056@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Shakeel Butt commit cefc7ef3c87d02fc9307835868ff721ea12cc597 upstream. Syzbot instance running on upstream kernel found a use-after-free bug in oom_kill_process. On further inspection it seems like the process selected to be oom-killed has exited even before reaching read_lock(&tasklist_lock) in oom_kill_process(). More specifically the tsk->usage is 1 which is due to get_task_struct() in oom_evaluate_task() and the put_task_struct within for_each_thread() frees the tsk and for_each_thread() tries to access the tsk. The easiest fix is to do get/put across the for_each_thread() on the selected task. Now the next question is should we continue with the oom-kill as the previously selected task has exited? However before adding more complexity and heuristics, let's answer why we even look at the children of oom-kill selected task? The select_bad_process() has already selected the worst process in the system/memcg. Due to race, the selected process might not be the worst at the kill time but does that matter? The userspace can use the oom_score_adj interface to prefer children to be killed before the parent. I looked at the history but it seems like this is there before git history. Link: http://lkml.kernel.org/r/20190121215850.221745-1-shakeelb@google.com Reported-by: syzbot+7fbbfa368521945f0e3d@syzkaller.appspotmail.com Fixes: 6b0c81b3be11 ("mm, oom: reduce dependency on tasklist_lock") Signed-off-by: Shakeel Butt Reviewed-by: Roman Gushchin Acked-by: Michal Hocko Cc: David Rientjes Cc: Johannes Weiner Cc: Tetsuo Handa Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/oom_kill.c | 8 ++++++++ 1 file changed, 8 insertions(+) --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -870,6 +870,13 @@ static void oom_kill_process(struct oom_ * still freeing memory. */ read_lock(&tasklist_lock); + + /* + * The task 'p' might have already exited before reaching here. The + * put_task_struct() will free task_struct 'p' while the loop still try + * to access the field of 'p', so, get an extra reference. + */ + get_task_struct(p); for_each_thread(p, t) { list_for_each_entry(child, &t->children, sibling) { unsigned int child_points; @@ -889,6 +896,7 @@ static void oom_kill_process(struct oom_ } } } + put_task_struct(p); read_unlock(&tasklist_lock); p = find_lock_task_mm(victim);