From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757384AbeDIB63 (ORCPT ); Sun, 8 Apr 2018 21:58:29 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:38076 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755291AbeDIB60 (ORCPT ); Sun, 8 Apr 2018 21:58:26 -0400 X-Google-Smtp-Source: AIpwx49znIq0mB7LYV9RXX2urQbz6RBt6WgWQ0INNvhy1y/MxDmN7bKlevIadYYMZ+Jmo9ybhlhnjg== From: Minchan Kim To: Andrew Morton Cc: linux-mm , LKML , Minchan Kim , Johannes Weiner , Jan Kara , Chris Fries Subject: [PATCH] mm: workingset: fix NULL ptr dereference Date: Mon, 9 Apr 2018 10:58:15 +0900 Message-Id: <20180409015815.235943-1-minchan@kernel.org> X-Mailer: git-send-email 2.17.0.484.g0c8726318c-goog Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Recently, I got a report like below. [ 7858.792946] [] __list_del_entry+0x30/0xd0 [ 7858.792951] [] list_lru_del+0xac/0x1ac [ 7858.792957] [] page_cache_tree_insert+0xd8/0x110 [ 7858.792962] [] __add_to_page_cache_locked+0xf8/0x4e0 [ 7858.792967] [] add_to_page_cache_lru+0x50/0x1ac [ 7858.792972] [] pagecache_get_page+0x468/0x57c [ 7858.792979] [] __get_node_page+0x84/0x764 [ 7858.792986] [] f2fs_iget+0x264/0xdc8 [ 7858.792991] [] f2fs_lookup+0x3b4/0x660 [ 7858.792998] [] lookup_slow+0x1e4/0x348 [ 7858.793003] [] walk_component+0x21c/0x320 [ 7858.793008] [] path_lookupat+0x90/0x1bc [ 7858.793013] [] filename_lookup+0x8c/0x1a0 [ 7858.793018] [] vfs_fstatat+0x84/0x10c [ 7858.793023] [] SyS_newfstatat+0x28/0x64 v4.9 kenrel already has the d3798ae8c6f3,("mm: filemap: don't plant shadow entries without radix tree node") so I thought it should be okay. When I was googling, I found others report such problem and I think current kernel still has the problem. https://bugzilla.redhat.com/show_bug.cgi?id=1431567 https://bugzilla.redhat.com/show_bug.cgi?id=1420335 It assumes shadow entry of radix tree relies on the init state that node->private_list allocated should be list_empty state. Currently, it's initailized in SLAB constructor which means node of radix tree would be initialized only when *slub allocates new page*, not *new object*. So, if some FS or subsystem pass gfp_mask to __GFP_ZERO, slub allocator will do memset blindly. That means allocated node can have !list_empty(node->private_list). It ends up calling NULL deference at workingset_update_node by failing list_empty check. This patch should fix it. Fixes: 449dd6984d0e ("mm: keep page cache radix tree nodes in check") Reported-by: Chris Fries Cc: Johannes Weiner Cc: Jan Kara Signed-off-by: Minchan Kim --- If it is reviewed and proved with testing, I will resend the patch to Ccing stable@vger.kernel.org. Thanks. lib/radix-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 8e00138d593f..afcbdb6c495f 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -428,6 +428,7 @@ radix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent, ret->exceptional = exceptional; ret->parent = parent; ret->root = root; + INIT_LIST_HEAD(&ret->private_list); } return ret; } @@ -2234,7 +2235,6 @@ radix_tree_node_ctor(void *arg) struct radix_tree_node *node = arg; memset(node, 0, sizeof(*node)); - INIT_LIST_HEAD(&node->private_list); } static __init unsigned long __maxindex(unsigned int height) -- 2.17.0.484.g0c8726318c-goog