From patchwork Wed Sep 14 12:37:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 16687 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 694B181D22; Wed, 14 Sep 2016 14:37:54 +0200 (CEST) Authentication-Results: open-mesh.org; dmarc=none header.from=simonwunderlich.de Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2001:4d88:2000:24::c0de; helo=mail.mail.packetmixer.de; envelope-from=sw@simonwunderlich.de; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dmarc=none header.from=simonwunderlich.de Received: from mail.mail.packetmixer.de (packetmixer.de [IPv6:2001:4d88:2000:24::c0de]) by open-mesh.org (Postfix) with ESMTPS id C867381D22 for ; Wed, 14 Sep 2016 14:37:45 +0200 (CEST) Received: from kero.packetmixer.de (p2003007C6F769E00527B9DFFFECE2EDC.dip0.t-ipconnect.de [IPv6:2003:7c:6f76:9e00:527b:9dff:fece:2edc]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mail.packetmixer.de (Postfix) with ESMTPSA id B25C11F0014; Wed, 14 Sep 2016 14:37:45 +0200 (CEST) From: Simon Wunderlich To: davem@davemloft.net Date: Wed, 14 Sep 2016 14:37:34 +0200 Message-Id: <20160914123735.9411-2-sw@simonwunderlich.de> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160914123735.9411-1-sw@simonwunderlich.de> References: <20160914123735.9411-1-sw@simonwunderlich.de> Cc: netdev@vger.kernel.org, b.a.t.m.a.n@lists.open-mesh.org, Marek Lindner Subject: [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Add missing refcnt for last_candidate X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 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" From: Sven Eckelmann batadv_find_router dereferences last_bonding_candidate from orig_node without making sure that it has a valid reference. This reference has to be retrieved by increasing the reference counter while holding neigh_list_lock. The lock is required to avoid that batadv_last_bonding_replace removes the current last_bonding_candidate, reduces the reference counter and maybe destroys the object in this process. Fixes: f3b3d9018975 ("batman-adv: add bonding again") Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Simon Wunderlich --- net/batman-adv/routing.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 7602c00..3d19947 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -470,6 +470,29 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, } /** + * batadv_last_bonding_get - Get last_bonding_candidate of orig_node + * @orig_node: originator node whose last bonding candidate should be retrieved + * + * Return: last bonding candidate of router or NULL if not found + * + * The object is returned with refcounter increased by 1. + */ +static struct batadv_orig_ifinfo * +batadv_last_bonding_get(struct batadv_orig_node *orig_node) +{ + struct batadv_orig_ifinfo *last_bonding_candidate; + + spin_lock_bh(&orig_node->neigh_list_lock); + last_bonding_candidate = orig_node->last_bonding_candidate; + + if (last_bonding_candidate) + kref_get(&last_bonding_candidate->refcount); + spin_unlock_bh(&orig_node->neigh_list_lock); + + return last_bonding_candidate; +} + +/** * batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node * @orig_node: originator node whose bonding candidates should be replaced * @new_candidate: new bonding candidate or NULL @@ -539,7 +562,7 @@ batadv_find_router(struct batadv_priv *bat_priv, * router - obviously there are no other candidates. */ rcu_read_lock(); - last_candidate = orig_node->last_bonding_candidate; + last_candidate = batadv_last_bonding_get(orig_node); if (last_candidate) last_cand_router = rcu_dereference(last_candidate->router); @@ -631,6 +654,9 @@ next: batadv_orig_ifinfo_put(next_candidate); } + if (last_candidate) + batadv_orig_ifinfo_put(last_candidate); + return router; }