From patchwork Fri Jun 9 08:13:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hangbin Liu X-Patchwork-Id: 773708 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3wkZpC3Wh5z9s4s for ; Fri, 9 Jun 2017 18:14:43 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="g7Q5jblJ"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751538AbdFIIOk (ORCPT ); Fri, 9 Jun 2017 04:14:40 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:33849 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751516AbdFIIOh (ORCPT ); Fri, 9 Jun 2017 04:14:37 -0400 Received: by mail-pg0-f68.google.com with SMTP id v14so7051889pgn.1 for ; Fri, 09 Jun 2017 01:14:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=3lpmHBrOH61QcMicoJgwsUO8qamQ0hctdcNHGp8pjj0=; b=g7Q5jblJEJiBzPHW5oA6eLCzgG5uCUpKv7nCjw151XnPIi4tgbxwYYTfTUCd7KGfpn n8RdWi40BjdySL1tnEU3Tz3MR9LcCzh8RTQYZWywjtMqhthGUIlY9YmihKDB0McOK4z2 9b/SDLc7eAUybRSOuSY1axyawxrdCiESRutSVrzM7ArUw1KHUsO3dNA8l5SqhfHbUgoG DZXokpnrretIqbqylfrEpQ0QpcVnMAk08C/CfxavjErULSmDN/H6ebtck+FV2Nfy4iYe C0MwMA+qRtmLN2xuy2FYzs4YRM7mVdbyIW55ZBgKl5+TDWoYbPhAFuaV/z6a2jPaZbhb yN+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=3lpmHBrOH61QcMicoJgwsUO8qamQ0hctdcNHGp8pjj0=; b=EqyOeKJkTGFB+5YRj/rfE3Mqt3q9+YuzLHlImorp52GM/GCvktsF5+EYt5y1Qt4ueA amMgM92XUBbQ+pKaUyKKuiix0ZfzdSLLNMd7Ub9ub/ibmLM82KwH/gn0GbQNyE1ZJ0JN wjl9rVsO2JuTqYqd0W+Tkod2ydVAfMQNddKhpxinM8yePfR/99owjJ8OZ6823dmEPlfP CBgDY3uQEwt3FYiDFcrWT5VcYyJfuuF/bT/C1mAZ39PQa2vuG8/RRqCbWY5cUUSaXt7R 4PDu9YVLW9oWUV29/EcSdt/UOEeXdJ6+KjNEcvhS+n/A6zBM4GYdj8DlufL/1Eqsin4k m8AQ== X-Gm-Message-State: AODbwcBnzjb6V7YsVh9ChvY+pI0vafkyZZejo5BibxyScBurax8op3MW S64R4abEGsvVErSGHHY= X-Received: by 10.98.204.71 with SMTP id a68mr11313140pfg.59.1496996076342; Fri, 09 Jun 2017 01:14:36 -0700 (PDT) Received: from leo.usersys.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id p76sm1314266pfa.53.2017.06.09.01.14.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Jun 2017 01:14:35 -0700 (PDT) From: Hangbin Liu To: netdev@vger.kernel.org Cc: David Miller , Xin Long , Steffen Klassert , Hangbin Liu Subject: [PATCH net] net/flow: fix fc->percpu NULL pointer dereference Date: Fri, 9 Jun 2017 16:13:56 +0800 Message-Id: <1496996036-22077-1-git-send-email-liuhangbin@gmail.com> X-Mailer: git-send-email 2.5.5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Now we will force to do garbage collection if any policy removed in xfrm_policy_flush(). But during xfrm_net_exit(). We call flow_cache_fini() first and set set fc->percpu to NULL. Then after we call xfrm_policy_fini() -> frxm_policy_flush() -> flow_cache_flush(), we will get NULL pointer dereference when check percpu_empty. The code path looks like: flow_cache_fini() - fc->percpu = NULL xfrm_policy_fini() - xfrm_policy_flush() - xfrm_garbage_collect() - flow_cache_flush() - flow_cache_percpu_empty() - fcp = per_cpu_ptr(fc->percpu, cpu) To reproduce, just add ipsec in netns and then remove the netns. Fixes: 35db06912189 ("xfrm: do the garbage collection after flushing policy") Signed-off-by: Hangbin Liu --- net/core/flow.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/core/flow.c b/net/core/flow.c index f7f5d19..321fc53 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -332,10 +332,13 @@ static int flow_cache_percpu_empty(struct flow_cache *fc, int cpu) struct flow_cache_percpu *fcp; unsigned int i; - fcp = per_cpu_ptr(fc->percpu, cpu); - for (i = 0; i < flow_cache_hash_size(fc); i++) - if (!hlist_empty(&fcp->hash_table[i])) - return 0; + if (fc->percpu) { + fcp = per_cpu_ptr(fc->percpu, cpu); + for (i = 0; i < flow_cache_hash_size(fc); i++) + if (!hlist_empty(&fcp->hash_table[i])) + return 0; + } + return 1; }