Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp3881635pxb; Tue, 17 Nov 2020 06:07:24 -0800 (PST) X-Google-Smtp-Source: ABdhPJxZPCrXbHQwYxvsQMtfgYVgc5mpRcNRWWtR5jC7F58gls62PZ+VOvSW0N6FyfJ1RMAvIhIT X-Received: by 2002:a17:906:468d:: with SMTP id a13mr20237859ejr.253.1605622044253; Tue, 17 Nov 2020 06:07:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605622044; cv=none; d=google.com; s=arc-20160816; b=XAHud6LjagpyIK/GGnUZK2H+9wnKuBDD/+2b6Y/nZ4UXrCviMTyLvQDgGKkA/Uu1zS fQmDbK0+nD6/nfyKB3j6ripsI7aCfOixMDN9+9bzEuSzRP4yj/zn8+BKd+jBoYKHm70k KfzQ6L62fZcqQgzSj9XkqZ4G/XM91c/Yvq2aEPP0tcePIVj97dTPixaws9nC+R3Rs72U Gu++599ZhLqwRPJdTqrQMcJM+myBxN5wXHxvMbssfU1jlP4kCDSR3IyXYFqMHAU5xFaM zyF5V+ihnQ+Z0r72E7GQOJbTz4ZOEW+pR7rR/8SHMJA+wjkw9pX1F+LYasXLt0bSATkm 6f/w== 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=k1gbCemN4jmbbgHXYJkCDHWkNMlPPqcCChLAuPMS+yw=; b=gOn6cZmnSHigH4cZg286d2EfMSmjqE76AQ0+Rkul4aqGsDlc3NWk/2auXP11d+GE9b +A7jyt0x8kNll2HkgxGSIA76H7OVkcJ/7HlZ6uUurQwJPkMhpTz/ujGKC2Tj0FrjBwv+ UIivxzVYVVLFuwGpViPW0OFy+EPst3whP/QUhgYw4fZH8N847u9D+Q+3DVfvJIA2TRp/ fa8HlH0QOIEL8NkpQhiKhPFuvYWKiG/SNwKksJ4RtSP5h1Q4IT7dDls5Pt01p2CLIq8p GBi3PaLqQ6lWPIQ3XS4FGxM35XJ6ZR9SfLgiJCwsLbGk3jwKV8fxeSRRCdFfpXWTYsJT W5Fg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="muv4/mCH"; 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=fail (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 v10si13474659ejg.0.2020.11.17.06.06.57; Tue, 17 Nov 2020 06:07:24 -0800 (PST) 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=@kernel.org header.s=default header.b="muv4/mCH"; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731118AbgKQOCe (ORCPT + 99 others); Tue, 17 Nov 2020 09:02:34 -0500 Received: from mail.kernel.org ([198.145.29.99]:43602 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729937AbgKQNNR (ORCPT ); Tue, 17 Nov 2020 08:13:17 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 97DAF241A5; Tue, 17 Nov 2020 13:13:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605618795; bh=3Ctmw80OXu6Bsy+X7/2vucJp1FoYS/pIixt1QcdspZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=muv4/mCHN4x2V3zOh8498PMzBrSJgMlMlFM8LrFcVKpEb9NEZFWP8fOeA1vsn8Chu qTOuUYJjDe7AKnb70qkKgdi8O4G/sw0Uiuz8N9LSpPski5VhicMGJkbKT/QSPXdm7T vyL5m3T33cet+rUDOmYUm2Kec1QZ6OKhjHO5iuLg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, zhuoliang zhang , Herbert Xu , Steffen Klassert , Sasha Levin Subject: [PATCH 4.14 10/85] net: xfrm: fix a race condition during allocing spi Date: Tue, 17 Nov 2020 14:04:39 +0100 Message-Id: <20201117122111.533392945@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201117122111.018425544@linuxfoundation.org> References: <20201117122111.018425544@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: zhuoliang zhang [ Upstream commit a779d91314ca7208b7feb3ad817b62904397c56d ] we found that the following race condition exists in xfrm_alloc_userspi flow: user thread state_hash_work thread ---- ---- xfrm_alloc_userspi() __find_acq_core() /*alloc new xfrm_state:x*/ xfrm_state_alloc() /*schedule state_hash_work thread*/ xfrm_hash_grow_check() xfrm_hash_resize() xfrm_alloc_spi /*hold lock*/ x->id.spi = htonl(spi) spin_lock_bh(&net->xfrm.xfrm_state_lock) /*waiting lock release*/ xfrm_hash_transfer() spin_lock_bh(&net->xfrm.xfrm_state_lock) /*add x into hlist:net->xfrm.state_byspi*/ hlist_add_head_rcu(&x->byspi) spin_unlock_bh(&net->xfrm.xfrm_state_lock) /*add x into hlist:net->xfrm.state_byspi 2 times*/ hlist_add_head_rcu(&x->byspi) 1. a new state x is alloced in xfrm_state_alloc() and added into the bydst hlist in __find_acq_core() on the LHS; 2. on the RHS, state_hash_work thread travels the old bydst and tranfers every xfrm_state (include x) into the new bydst hlist and new byspi hlist; 3. user thread on the LHS gets the lock and adds x into the new byspi hlist again. So the same xfrm_state (x) is added into the same list_hash (net->xfrm.state_byspi) 2 times that makes the list_hash become an inifite loop. To fix the race, x->id.spi = htonl(spi) in the xfrm_alloc_spi() is moved to the back of spin_lock_bh, sothat state_hash_work thread no longer add x which id.spi is zero into the hash_list. Fixes: f034b5d4efdf ("[XFRM]: Dynamic xfrm_state hash table sizing.") Signed-off-by: zhuoliang zhang Acked-by: Herbert Xu Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/xfrm/xfrm_state.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 05c275a712f11..5164dfe0aa097 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1783,6 +1783,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) int err = -ENOENT; __be32 minspi = htonl(low); __be32 maxspi = htonl(high); + __be32 newspi = 0; u32 mark = x->mark.v & x->mark.m; spin_lock_bh(&x->lock); @@ -1801,21 +1802,22 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) xfrm_state_put(x0); goto unlock; } - x->id.spi = minspi; + newspi = minspi; } else { u32 spi = 0; for (h = 0; h < high-low+1; h++) { spi = low + prandom_u32()%(high-low+1); x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); if (x0 == NULL) { - x->id.spi = htonl(spi); + newspi = htonl(spi); break; } xfrm_state_put(x0); } } - if (x->id.spi) { + if (newspi) { spin_lock_bh(&net->xfrm.xfrm_state_lock); + x->id.spi = newspi; h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family); hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); spin_unlock_bh(&net->xfrm.xfrm_state_lock); -- 2.27.0