Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4225930pxf; Tue, 16 Mar 2021 08:26:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJycfJ+iSSztdDWlqpgxU7d31V13GmYzsDvQ4zj5w+wkVRSJtPmACF72TkxhIkzm7i9tIFhD X-Received: by 2002:aa7:c5c4:: with SMTP id h4mr35393973eds.375.1615908376625; Tue, 16 Mar 2021 08:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1615908376; cv=none; d=google.com; s=arc-20160816; b=WEO5MlTxp43m1S/hWWtw2xF8/sQf8a3ldGoVEoQdwkgU0wmzaMNRc0/4v7GUMSUJ5Y 4GQyKgA/DIfzBLrXETd9unvrXb5rKzQPJHl74SO0NIkd609C6dinDPsQ+z9nO3as6fNv 6imy/Zmrtm8RPlMuiYj18qAYh2Ge3So3lTublGWfbkvIfjtKgIFgvmKd4eJ+/39TMv9P KefaeebkPPN/INlupsIK39VZEpMeNcnkQ+O1lhlTPkOpbBY4H+Qn3NyjTlcDQgpAOu/I sk9aTLSU5D5SSGLUaF1BbgZ2N5SmewEnEcW12oKfNryQNwZEWHKKodExdBH149u0bRLr 3ZDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:dkim-signature :dkim-signature:from; bh=58x31dgR3ei2wUVCbrduJffIzcrW5zLw96q/fq4bJoU=; b=rhI0SPbnkxp6a5boX4hep0GHmWs03T5pug4QZlGZqRIWNym5eVKpgdJTQZ1N7Dd84o GCzEUNtGOc6qhJCXDfHgsDIED6HDMkD/zfTdw4VKWJ5mF1MrP5alwZI4c0ZJUQyrV/Ny Af8zqqlbVHI6WJfDOFECfZrW/7WPo//FtG7haq21U973XpC/ggLn9D0TDwOauAJx7JGS /NnpneU0/EJbrkpUCwrFyethblKMzEYjfOPwUqjkby4cyr03hXWYuescCpQ35QHjTF9s AU0ecKIM0xJtD7/adRYLSHKfelF418mo+Z/1jtj5yYkOm5s83kbFd30fl3XuY42SPgfa +hiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="mCL/d4Te"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=PTPBcPfy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k12si14389549edq.82.2021.03.16.08.25.52; Tue, 16 Mar 2021 08:26:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="mCL/d4Te"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=PTPBcPfy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236923AbhCPK5U (ORCPT + 99 others); Tue, 16 Mar 2021 06:57:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232565AbhCPK4h (ORCPT ); Tue, 16 Mar 2021 06:56:37 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4926CC06174A; Tue, 16 Mar 2021 03:56:37 -0700 (PDT) From: "Ahmed S. Darwish" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1615892194; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=58x31dgR3ei2wUVCbrduJffIzcrW5zLw96q/fq4bJoU=; b=mCL/d4Tewv/S9NfDGEdeKv+KaVbN3/EvFwwoQaLQfwULfUSygFxsK8+Ju3LLjSjeGYS9vP tirhSST7OKEnTdE8XXhBBe9nk5vpGAK2zia6OJ+coTWq5SiIXEvtwMlFCecI1pIZY6ktfV 5I834OvTf1++rNDsKT9HeUDaR2nPx8wo4j34Y0QIp+a5BMDOn9xcFeMKovXX2AMO79ngzi feARFsZ8uOGG7U2VnWJ3XTpcdz5VA4vxWBcdFICauyOjlmykLW8430Ug7MlZu+o/CDYKZs CDSxD9Irk1tAEIVdgupYPjB6UhKuYd0VWVQLIcjSnR8+05F+pqTbYZmjJcCXQQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1615892194; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=58x31dgR3ei2wUVCbrduJffIzcrW5zLw96q/fq4bJoU=; b=PTPBcPfyY+ZMFyEZ8fZ5zKS1ChlY4VODmVrt8rA72HeqO5+a2OYwNwOeWgf/TDDNZxmzks xKDKPzx5FdSkreBw== To: Steffen Klassert , Herbert Xu , "David S. Miller" , Jakub Kicinski Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Gleixner , "Sebastian A. Siewior" , "Ahmed S. Darwish" Subject: [PATCH v1 1/2] net: xfrm: Localize sequence counter per network namespace Date: Tue, 16 Mar 2021 11:56:29 +0100 Message-Id: <20210316105630.1020270-2-a.darwish@linutronix.de> In-Reply-To: <20210316105630.1020270-1-a.darwish@linutronix.de> References: <20210316105630.1020270-1-a.darwish@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A sequence counter write section must be serialized or its internal state can get corrupted. The "xfrm_state_hash_generation" seqcount is global, but its write serialization lock (net->xfrm.xfrm_state_lock) is instantiated per network namespace. The write protection is thus insufficient. To provide full protection, localize the sequence counter per network namespace instead. This should be safe as both the seqcount read and write sections access data exclusively within the network namespace. It also lays the foundation for transforming "xfrm_state_hash_generation" data type from seqcount_t to seqcount_LOCKNAME_t in further commits. Fixes: b65e3d7be06f ("xfrm: state: add sequence count to detect hash resizes") Signed-off-by: Ahmed S. Darwish --- include/net/netns/xfrm.h | 4 +++- net/xfrm/xfrm_state.c | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 59f45b1e9dac..b59d73d529ba 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -72,7 +72,9 @@ struct netns_xfrm { #if IS_ENABLED(CONFIG_IPV6) struct dst_ops xfrm6_dst_ops; #endif - spinlock_t xfrm_state_lock; + spinlock_t xfrm_state_lock; + seqcount_t xfrm_state_hash_generation; + spinlock_t xfrm_policy_lock; struct mutex xfrm_cfg_mutex; }; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d01ca1a18418..ffd315cff984 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -44,7 +44,6 @@ static void xfrm_state_gc_task(struct work_struct *work); */ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; -static __read_mostly seqcount_t xfrm_state_hash_generation = SEQCNT_ZERO(xfrm_state_hash_generation); static struct kmem_cache *xfrm_state_cache __ro_after_init; static DECLARE_WORK(xfrm_state_gc_work, xfrm_state_gc_task); @@ -140,7 +139,7 @@ static void xfrm_hash_resize(struct work_struct *work) } spin_lock_bh(&net->xfrm.xfrm_state_lock); - write_seqcount_begin(&xfrm_state_hash_generation); + write_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; odst = xfrm_state_deref_prot(net->xfrm.state_bydst, net); @@ -156,7 +155,7 @@ static void xfrm_hash_resize(struct work_struct *work) rcu_assign_pointer(net->xfrm.state_byspi, nspi); net->xfrm.state_hmask = nhashmask; - write_seqcount_end(&xfrm_state_hash_generation); + write_seqcount_end(&net->xfrm.xfrm_state_hash_generation); spin_unlock_bh(&net->xfrm.xfrm_state_lock); osize = (ohashmask + 1) * sizeof(struct hlist_head); @@ -1063,7 +1062,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, to_put = NULL; - sequence = read_seqcount_begin(&xfrm_state_hash_generation); + sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); rcu_read_lock(); h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); @@ -1176,7 +1175,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, if (to_put) xfrm_state_put(to_put); - if (read_seqcount_retry(&xfrm_state_hash_generation, sequence)) { + if (read_seqcount_retry(&net->xfrm.xfrm_state_hash_generation, sequence)) { *err = -EAGAIN; if (x) { xfrm_state_put(x); @@ -2666,6 +2665,7 @@ int __net_init xfrm_state_init(struct net *net) net->xfrm.state_num = 0; INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); spin_lock_init(&net->xfrm.xfrm_state_lock); + seqcount_init(&net->xfrm.xfrm_state_hash_generation); return 0; out_byspi: -- 2.30.2