From patchwork Wed May 9 19:07:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 17350 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 55C37826AA; Wed, 9 May 2018 21:07:54 +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="DVAlDY3X"; 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 51B0A801C8 for ; Wed, 9 May 2018 21:07:52 +0200 (CEST) Received: from sven-desktop.home.narfation.org (p200300C593C84EF90000000000004065.dip0.t-ipconnect.de [IPv6:2003:c5:93c8:4ef9::4065]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 754181100D5; Wed, 9 May 2018 21:07:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=narfation.org; s=20121; t=1525892871; bh=+0oNn7uys/N0sfJrMdCeqnZVE7CaX28MX+pjxyT+Bk0=; h=From:To:Cc:Subject:Date:From; b=DVAlDY3XlvBF9Zyu4Hh5EZhlVTCNesEUEyiM6SN3j2uoE64YjDBj6l9jqKdAszBL8 ET2EPPs9M35qGzPHics1OE6IJkI7XNh2RxZIcyWXOMYe5sxKVw62g8v2DxX0xDGk50 zLs7snUEnPsSKqZs1qNHjbR9KW/O9lf6W0UUqmzk= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Wed, 9 May 2018 21:07:40 +0200 Message-Id: <20180509190740.11465-1-sven@narfation.org> X-Mailer: git-send-email 2.17.0 Subject: [B.A.T.M.A.N.] [PATCH maint v2] batman-adv: Avoid race in TT TVLV allocator helper 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 functions batadv_tt_prepare_tvlv_local_data and batadv_tt_prepare_tvlv_global_data are responsible for preparing a buffer which can be used to store the TVLV container for TT and add the VLAN information to it. This will be done in three phases: 1. count the number of VLANs and their entries 2. allocate the buffer using the counters from the previous step and limits from the caller (parameter tt_len) 3. insert the VLAN information to the buffer The step 1 and 3 operate on a list which contains the VLANs. The access to these lists must be protected with an appropriate lock or otherwise they might operate on on different entries. This could for example happen when another context is adding VLAN entries to this list. This could lead to a buffer overflow in these functions when enough entries were added between step 1 and 3 to the VLAN lists that the buffer room for the entries (*tt_change) is smaller then the now required extra buffer for new VLAN entries. Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific") Signed-off-by: Sven Eckelmann Acked-by: Antonio Quartulli --- v2: - adjusted last paragraph because tt_change (third parameter "return") doesn't depend on step 3 This change is completely untested. The issue for this problem can be found in https://www.open-mesh.org/issues/354 net/batman-adv/translation-table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 0225616d..7fa3a0a0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, struct batadv_orig_node_vlan *vlan; u8 *tt_change_ptr; - rcu_read_lock(); + spin_lock_bh(&orig_node->vlan_list_lock); hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { num_vlan++; num_entries += atomic_read(&vlan->tt.num_entries); @@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; out: - rcu_read_unlock(); + spin_unlock_bh(&orig_node->vlan_list_lock); return tvlv_len; } @@ -936,7 +936,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, u8 *tt_change_ptr; int change_offset; - rcu_read_lock(); + spin_lock_bh(&bat_priv->softif_vlan_list_lock); hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { num_vlan++; num_entries += atomic_read(&vlan->tt.num_entries); @@ -974,7 +974,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; out: - rcu_read_unlock(); + spin_unlock_bh(&bat_priv->softif_vlan_list_lock); return tvlv_len; }