batman-adv: 2015.0 bugfixes & stability updates
[feed/routing.git] / batman-adv / patches / 0010-batman-adv-protect-tt_local_entry-from-concurrent-de.patch
1 From af912d77181f252e6fdd324592d006e30bc82909 Mon Sep 17 00:00:00 2001
2 From: Marek Lindner <mareklindner@neomailbox.ch>
3 Date: Wed, 17 Jun 2015 20:01:36 +0800
4 Subject: [PATCH 10/13] batman-adv: protect tt_local_entry from concurrent
5 delete events
6
7 The tt_local_entry deletion performed in batadv_tt_local_remove() was neither
8 protecting against simultaneous deletes nor checking whether the element was
9 still part of the list before calling hlist_del_rcu().
10
11 Replacing the hlist_del_rcu() call with batadv_hash_remove() provides adequate
12 protection via hash spinlocks as well as an is-element-still-in-hash check to
13 avoid 'blind' hash removal.
14
15 Fixes: 2443ba3 ("batman-adv: roaming handling mechanism redesign")
16
17 Reported-by: alfonsname@web.de
18 Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
19 Acked-by: Antonio Quartulli <antonio@meshcoding.com>
20 ---
21 translation-table.c | 11 ++++++++++-
22 1 file changed, 10 insertions(+), 1 deletion(-)
23
24 diff --git a/translation-table.c b/translation-table.c
25 index 807a4e6..dfe8896 100644
26 --- a/translation-table.c
27 +++ b/translation-table.c
28 @@ -1019,6 +1019,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
29 struct batadv_tt_local_entry *tt_local_entry;
30 uint16_t flags, curr_flags = BATADV_NO_FLAGS;
31 struct batadv_softif_vlan *vlan;
32 + void *tt_entry_exists;
33
34 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
35 if (!tt_local_entry)
36 @@ -1046,7 +1047,15 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
37 * immediately purge it
38 */
39 batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
40 - hlist_del_rcu(&tt_local_entry->common.hash_entry);
41 +
42 + tt_entry_exists = batadv_hash_remove(bat_priv->tt.local_hash,
43 + batadv_compare_tt,
44 + batadv_choose_tt,
45 + &tt_local_entry->common);
46 + if (!tt_entry_exists)
47 + goto out;
48 +
49 + /* extra call to free the local tt entry */
50 batadv_tt_local_entry_free_ref(tt_local_entry);
51
52 /* decrease the reference held for this vlan */
53 --
54 2.1.4
55