diff options
Diffstat (limited to 'batman-adv/patches/0037-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch')
| -rw-r--r-- | batman-adv/patches/0037-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/batman-adv/patches/0037-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch b/batman-adv/patches/0037-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch new file mode 100644 index 0000000..964089e --- /dev/null +++ b/batman-adv/patches/0037-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch @@ -0,0 +1,75 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Wed, 9 May 2018 21:07:40 +0200 +Subject: [PATCH] batman-adv: Avoid race in TT TVLV allocator helper + +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 <sven@narfation.org> +Acked-by: Antonio Quartulli <a@unstable.cc> + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/286be89a33497ba9000aa5c2960f1f4114953522 +--- + 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 a64003b824e0d0b05f0a9e44ccc32ba0cb3018fc..933ac64b5707846ddee9f828b538ade86b968986 100644 +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -860,7 +860,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); +@@ -898,7 +898,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; + } + +@@ -934,7 +934,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); +@@ -972,7 +972,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; + } + |
