From patchwork Thu Sep 6 12:35:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 17471 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from open-mesh.org (localhost [IPv6:::1]) by open-mesh.org (Postfix) with ESMTP id E92B982F5C; Thu, 6 Sep 2018 14:35:46 +0200 (CEST) Authentication-Results: open-mesh.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=narfation.org header.i=@narfation.org header.b="CDVbzBmu"; dkim-atps=neutral Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2001:4d88:2000:7::2; helo=v3-1039.vlinux.de; envelope-from=sven@narfation.org; receiver= Received: from v3-1039.vlinux.de (narfation.org [IPv6:2001:4d88:2000:7::2]) by open-mesh.org (Postfix) with ESMTPS id 707AB82F54 for ; Thu, 6 Sep 2018 14:35:45 +0200 (CEST) Received: from sven-desktop.home.narfation.org (p200300C593D79FFA9732AEE00057D068.dip0.t-ipconnect.de [IPv6:2003:c5:93d7:9ffa:9732:aee0:57:d068]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 0D7511100E1; Thu, 6 Sep 2018 14:35:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=narfation.org; s=20121; t=1536237344; bh=UtV+Dftyl+3r0oiu9hdo9+0ByXtTY5x0gs/GI2Y+zNQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CDVbzBmuleKEtY70198UlAV/NKLvQDGsd2XS38veRTo8FY+w1BUPRFs7fydrgiDki Iivz568FawRSQEHNn0ZGZpf0LcRvM4KXg6Slh2DIBfiRMZ1MghbJdc33l9e+lmUfVv tpqNNenwhGQlU5M0BEq8GF/azqOvdtLC4D3Q9uXM= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Thu, 6 Sep 2018 14:35:28 +0200 Message-Id: <20180906123528.30490-6-sven@narfation.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180906123528.30490-1-sven@narfation.org> References: <20180906123528.30490-1-sven@narfation.org> Subject: [B.A.T.M.A.N.] [PATCH v2 5/5] batman-adv: Prevent duplicated tvlv handler X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" The function batadv_tvlv_handler_register is responsible for adding new tvlv_handler to the handler_list. It first checks whether the entry already is in the list or not. If it is, then the creation of a new entry is aborted. But the lock for the list is only held when the list is really modified. This could lead to duplicated entries because another context could create an entry with the same key between the check and the list manipulation. The check and the manipulation of the list must therefore be in the same locked code section. Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure") Signed-off-by: Sven Eckelmann Acked-by: Marek Lindner --- net/batman-adv/tvlv.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c index a6374582..40e69c93 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, { struct batadv_tvlv_handler *tvlv_handler; + spin_lock_bh(&bat_priv->tvlv.handler_list_lock); + tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version); if (tvlv_handler) { + spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); batadv_tvlv_handler_put(tvlv_handler); return; } tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC); - if (!tvlv_handler) + if (!tvlv_handler) { + spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); return; + } tvlv_handler->ogm_handler = optr; tvlv_handler->unicast_handler = uptr; @@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, kref_init(&tvlv_handler->refcount); INIT_HLIST_NODE(&tvlv_handler->list); - spin_lock_bh(&bat_priv->tvlv.handler_list_lock); kref_get(&tvlv_handler->refcount); hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list); spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);