Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp1594363pxb; Mon, 12 Apr 2021 01:46:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxXiRR5V0+xLz0qn4oKwSBy7bDaV4Ey3oR8sIN1hHJqKDFVtcbyLhMf1V+k6Q49KbF19YnO X-Received: by 2002:a17:902:a589:b029:e9:21cc:4aac with SMTP id az9-20020a170902a589b02900e921cc4aacmr25380482plb.21.1618217180085; Mon, 12 Apr 2021 01:46:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618217180; cv=none; d=google.com; s=arc-20160816; b=HX4OWUZBOfC+HGhrTlh77XNhV0OV0oA4ug64CoqEPFveWGCTY30+/LxgjNMAwlltWp BHPSFvLhCfjG/u2Oolx9R7IHa5yM9zp8pWVt9pDkOqBvIFjPaOJmgz6A+ESCjNgRFNij azwPFV57ThXdwdQL232PDE+ccNhhcn2Rn7i/hZDlLED3gp3msvuzsr8/z5LLvBDIuEod 3ioB/rBAZ945Csm3T82D9jgbanvP8P1LiHX9ymFuKMt9KxIDFO5qLA76Fs85ErIt9c2l OOk/AhCPATA+OsZ7z88OOVH7zavOWg6ygKHoJZ1/RorhEai697xn5tyzMEg4oPNkp3iv 0ztQ== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=SFlNa6iRPOfh0sh0fNsGboYl5sZq8I31PPO9VeRvXFs=; b=kAi8LQDfzfYtIzbk5fnNICVleTe4HpRyedZmCXvU6CkCU+DoLsRDeHWg86Vr4bUiSG wmx3cOpYUg72WqIfRY+vY25+drH/QhNpXAxBHmJKlHoQFSFYIZQ3vTIN57PbHx/C6kAg f+sT1yB6Y1YVeNy0oRnYcGXkq2nsIqCEtITPVMAwEXZe/Ih/n/WQPqDNgMxo2ApNFcxu qYdXeMv3iT6KNMpu7mope/DvOT9lJh6CjIB6Rr7A0OUhF+qljuOzQ+qxDrmAo5xUT8PK X9cNEISw41zP5axj41ey89371PbblURydQUZ9AwSEpVzM3XooTTGbvrbaXvwbCCyWUHL 2+Zg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=CC4NDmrQ; 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=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o12si13342153pgj.23.2021.04.12.01.46.07; Mon, 12 Apr 2021 01:46:20 -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=@linuxfoundation.org header.s=korg header.b=CC4NDmrQ; 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=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237414AbhDLIoS (ORCPT + 99 others); Mon, 12 Apr 2021 04:44:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:35682 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237561AbhDLInx (ORCPT ); Mon, 12 Apr 2021 04:43:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4625D61221; Mon, 12 Apr 2021 08:43:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1618217015; bh=yZ4RDwF4eYw0HNvFN02ubTvSDkJz0zTvxg86LRgDtec=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CC4NDmrQUuqWmrrXWWzo4g5n5cT545LrhwADdAExEEhikSM4Iv81sEAjpZisP0a9N 9jNgU5B0htnPTM+pqW3oSMJOAGsbfDqujajRZlweXG7LuPJMZSvbITDn8jjE3YERen Ub5qSSwJPY4oCeeQ7SUArB7iPTh+JV/TAWdQL7S0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Ahmed S. Darwish" , Steffen Klassert , Sasha Levin Subject: [PATCH 4.19 31/66] net: xfrm: Localize sequence counter per network namespace Date: Mon, 12 Apr 2021 10:40:37 +0200 Message-Id: <20210412083959.133534415@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210412083958.129944265@linuxfoundation.org> References: <20210412083958.129944265@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ahmed S. Darwish [ Upstream commit e88add19f68191448427a6e4eb059664650a837f ] 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 Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- 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 9991e5ef52cc..fbfa59801454 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -70,7 +70,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 84dea0ad1666..44acc724122b 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -41,7 +41,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); @@ -137,7 +136,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); @@ -153,7 +152,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); @@ -965,7 +964,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); @@ -1076,7 +1075,7 @@ out: 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); @@ -2406,6 +2405,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