batman-adv: add patches from 2018.1-maint 2018-06-03
[feed/routing.git] / batman-adv / patches / 0002-batman-adv-Avoid-race-in-TT-TVLV-allocator-helper.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Wed, 9 May 2018 21:07:40 +0200
3 Subject: [PATCH] batman-adv: Avoid race in TT TVLV allocator helper
4
5 The functions batadv_tt_prepare_tvlv_local_data and
6 batadv_tt_prepare_tvlv_global_data are responsible for preparing a buffer
7 which can be used to store the TVLV container for TT and add the VLAN
8 information to it.
9
10 This will be done in three phases:
11
12 1. count the number of VLANs and their entries
13 2. allocate the buffer using the counters from the previous step and limits
14 from the caller (parameter tt_len)
15 3. insert the VLAN information to the buffer
16
17 The step 1 and 3 operate on a list which contains the VLANs. The access to
18 these lists must be protected with an appropriate lock or otherwise they
19 might operate on on different entries. This could for example happen when
20 another context is adding VLAN entries to this list.
21
22 This could lead to a buffer overflow in these functions when enough entries
23 were added between step 1 and 3 to the VLAN lists that the buffer room for
24 the entries (*tt_change) is smaller then the now required extra buffer for
25 new VLAN entries.
26
27 Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific")
28 Signed-off-by: Sven Eckelmann <sven@narfation.org>
29 Acked-by: Antonio Quartulli <a@unstable.cc>
30
31 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/286be89a33497ba9000aa5c2960f1f4114953522
32 ---
33 net/batman-adv/translation-table.c | 8 ++++----
34 1 file changed, 4 insertions(+), 4 deletions(-)
35
36 diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
37 index 0225616d5771d0986127322142fc591780fc25b0..7fa3a0a0524a1da63e92d081b443c302900bf0c3 100644
38 --- a/net/batman-adv/translation-table.c
39 +++ b/net/batman-adv/translation-table.c
40 @@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
41 struct batadv_orig_node_vlan *vlan;
42 u8 *tt_change_ptr;
43
44 - rcu_read_lock();
45 + spin_lock_bh(&orig_node->vlan_list_lock);
46 hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
47 num_vlan++;
48 num_entries += atomic_read(&vlan->tt.num_entries);
49 @@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
50 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
51
52 out:
53 - rcu_read_unlock();
54 + spin_unlock_bh(&orig_node->vlan_list_lock);
55 return tvlv_len;
56 }
57
58 @@ -936,7 +936,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
59 u8 *tt_change_ptr;
60 int change_offset;
61
62 - rcu_read_lock();
63 + spin_lock_bh(&bat_priv->softif_vlan_list_lock);
64 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
65 num_vlan++;
66 num_entries += atomic_read(&vlan->tt.num_entries);
67 @@ -974,7 +974,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
68 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
69
70 out:
71 - rcu_read_unlock();
72 + spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
73 return tvlv_len;
74 }
75