From patchwork Wed Aug 10 21:36:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 657948 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 3s8kwt31Vjz9s9G for ; Thu, 11 Aug 2016 07:36:14 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=QwqlW3PW; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752189AbcHJVgJ (ORCPT ); Wed, 10 Aug 2016 17:36:09 -0400 Received: from mail-pa0-f66.google.com ([209.85.220.66]:35858 "EHLO mail-pa0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751075AbcHJVgG (ORCPT ); Wed, 10 Aug 2016 17:36:06 -0400 Received: by mail-pa0-f66.google.com with SMTP id ez1so3427751pab.3; Wed, 10 Aug 2016 14:36:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RU3b6/cKeP+tcgow6C03JJ+QnIQUn8xS28o7JmHkBdI=; b=QwqlW3PWg/TiGCIYkMPxA72pkPrfelSpnnfndg7ZyX7kZH5y8jFKECuiybBboblHuM Jx0HwcSh87MIMyxs2dIsiYjpmhlQU6znvMNP5q4Up2lktHvAoXolm6XAxOUBd6d8RhtV eNLQWapPG4W01A6GQvMz4i2oAMWL2nDj5bT/uKLOWmZ7S31VsI/DEC4xSpkpU/inu5Vo sx0WvDW5b1IFivfwe+CNTumu6xNHZLQn+5R/5KUu6GoizylmzBKQjtzaK0ZJayd/fL1e 50WPxem7IlRzg+ReZC8aHrlRTVZH4oaoPc7IJhIq9rPrkeh/aV7y+8Hm2Ou2H4QYTX65 1uwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RU3b6/cKeP+tcgow6C03JJ+QnIQUn8xS28o7JmHkBdI=; b=dIMvy68Hv21ucA27yBW+V7l79WrzNu1h8iCZL/vAwzcAiJlO7gUcaYtZPt91fEr1ug Z6n2OTA3qFEv7WVweRFNNHqsV3cJ7ZJMK9UTbevUsv2WY0DbJoXAK64+z7tDw59DViS6 by4XW6gHRujLVNDknR5zDujXjSOI9lnFPiZDqVPGCy1ONMC8wphLl55Ov/1kkhLydIF3 BpYFQJCDRMgGfmpEY1WKkrZSqMr4T4S1Q59vTvSymyk78XzoSlEGq63D11VXYTq69XBd 4jpN2NAaoVSUsGzLzGxrhYvlcdJcKc09R263HFggCkEhT5y2JPxN5YRpzRLPZ8geHCSV nRwQ== X-Gm-Message-State: AEkoousS6YmQtFaEn1rn+ATYqVFsTbk1AU53qHbERyokgbGfMA4LWFdzteAugaJlQdiarA== X-Received: by 10.66.164.227 with SMTP id yt3mr10854456pab.117.1470864965434; Wed, 10 Aug 2016 14:36:05 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([172.22.152.21]) by smtp.gmail.com with ESMTPSA id fj19sm66408660pab.37.2016.08.10.14.36.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 10 Aug 2016 14:36:04 -0700 (PDT) From: Dmitry Torokhov To: "Eric W. Biederman" , "David S. Miller" Cc: Al Viro , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 1/3] netns: do not call pernet ops for not yet set up init_net namespace Date: Wed, 10 Aug 2016 14:36:00 -0700 Message-Id: <1470864962-25056-2-git-send-email-dmitry.torokhov@gmail.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1470864962-25056-1-git-send-email-dmitry.torokhov@gmail.com> References: <1470864962-25056-1-git-send-email-dmitry.torokhov@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When CONFIG_NET_NS is disabled, registering pernet operations causes init() to be called immediately with init_net as an argument. Unfortunately this leads to some pernet ops, such as proc_net_ns_init() to be called too early, when init_net namespace has not been fully initialized. This causes issues when we want to change pernet ops to use more data from the net namespace in question, for example reference user namespace that owns our network namespace. To fix this we could either play game of musical chairs and rearrange init order, or we could do the same as when CONFIG_NET_NS is enabled, and postpone calling pernet ops->init() until namespace is set up properly. Note that we can not simply undo commit ed160e839d2e ("[NET]: Cleanup pernet operation without CONFIG_NET_NS") and use the same implementations for __register_pernet_operations() and __unregister_pernet_operations(), because many pernet ops are marked as __net_initdata and will be discarded, which wreaks havoc on our ops lists. Here we rely on the fact that we only use lists until init_net is fully initialized, which happens much earlier than discarding __net_initdata sections. Signed-off-by: Dmitry Torokhov --- net/core/net_namespace.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 2c2eb1b..1fe5816 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -37,6 +37,8 @@ struct net init_net = { }; EXPORT_SYMBOL(init_net); +static bool init_net_initialized; + #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; @@ -750,6 +752,8 @@ static int __init net_ns_init(void) if (setup_net(&init_net, &init_user_ns)) panic("Could not setup the initial network namespace"); + init_net_initialized = true; + rtnl_lock(); list_add_tail_rcu(&init_net.list, &net_namespace_list); rtnl_unlock(); @@ -811,15 +815,24 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) { + if (!init_net_initialized) { + list_add_tail(&ops->list, list); + return 0; + } + return ops_init(ops, &init_net); } static void __unregister_pernet_operations(struct pernet_operations *ops) { - LIST_HEAD(net_exit_list); - list_add(&init_net.exit_list, &net_exit_list); - ops_exit_list(ops, &net_exit_list); - ops_free_list(ops, &net_exit_list); + if (!init_net_initialized) { + list_del(&ops->list); + } else { + LIST_HEAD(net_exit_list); + list_add(&init_net.exit_list, &net_exit_list); + ops_exit_list(ops, &net_exit_list); + ops_free_list(ops, &net_exit_list); + } } #endif /* CONFIG_NET_NS */