Skip to content

Commit 8ba0f9b

Browse files
ecsvsimonwunderlich
authored andcommitted
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: 7ea7b4a ("batman-adv: make the TT CRC logic VLAN specific") Signed-off-by: Sven Eckelmann <sven@narfation.org> Acked-by: Antonio Quartulli <a@unstable.cc> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
1 parent 65cc02a commit 8ba0f9b

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

net/batman-adv/translation-table.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
862862
struct batadv_orig_node_vlan *vlan;
863863
u8 *tt_change_ptr;
864864

865-
rcu_read_lock();
865+
spin_lock_bh(&orig_node->vlan_list_lock);
866866
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
867867
num_vlan++;
868868
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
900900
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
901901

902902
out:
903-
rcu_read_unlock();
903+
spin_unlock_bh(&orig_node->vlan_list_lock);
904904
return tvlv_len;
905905
}
906906

@@ -936,7 +936,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
936936
u8 *tt_change_ptr;
937937
int change_offset;
938938

939-
rcu_read_lock();
939+
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
940940
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
941941
num_vlan++;
942942
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -974,7 +974,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
974974
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
975975

976976
out:
977-
rcu_read_unlock();
977+
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
978978
return tvlv_len;
979979
}
980980

0 commit comments

Comments
 (0)