batman-adv: Merge bugfixes from 2018.3
[feed/routing.git] / batman-adv / patches / 0054-batman-adv-Prevent-duplicated-global-TT-entry.patch
diff --git a/batman-adv/patches/0054-batman-adv-Prevent-duplicated-global-TT-entry.patch b/batman-adv/patches/0054-batman-adv-Prevent-duplicated-global-TT-entry.patch
new file mode 100644 (file)
index 0000000..8fce2bf
--- /dev/null
@@ -0,0 +1,59 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 6 Sep 2018 14:35:27 +0200
+Subject: [PATCH] batman-adv: Prevent duplicated global TT entry
+
+The function batadv_tt_global_orig_entry_add is responsible for adding new
+tt_orig_list_entry to the orig_list. It first checks whether the entry
+already is in the list or not. If it is, then the creation of a new entry
+is aborted.
+
+But the lock for the list is only held when the list is really modified.
+This could lead to duplicated entries because another context could create
+an entry with the same key between the check and the list manipulation.
+
+The check and the manipulation of the list must therefore be in the same
+locked code section.
+
+Fixes: c5eb5bb30321 ("batman-adv: add reference counting for type batadv_tt_orig_list_entry")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/79097255a1a3e1bd1949be309af941181fbc7b36
+---
+ net/batman-adv/translation-table.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 143a00f90d1d925aad7113f897d06f435f28dcd8..b32853cbab028f0a052492545bb803efdcdb0ff3 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -1603,6 +1603,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
+ {
+       struct batadv_tt_orig_list_entry *orig_entry;
++      spin_lock_bh(&tt_global->list_lock);
++
+       orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
+       if (orig_entry) {
+               /* refresh the ttvn: the current value could be a bogus one that
+@@ -1625,11 +1627,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
+       orig_entry->flags = flags;
+       kref_init(&orig_entry->refcount);
+-      spin_lock_bh(&tt_global->list_lock);
+       kref_get(&orig_entry->refcount);
+       hlist_add_head_rcu(&orig_entry->list,
+                          &tt_global->orig_list);
+-      spin_unlock_bh(&tt_global->list_lock);
+       atomic_inc(&tt_global->orig_list_count);
+ sync_flags:
+@@ -1637,6 +1637,8 @@ sync_flags:
+ out:
+       if (orig_entry)
+               batadv_tt_orig_list_entry_put(orig_entry);
++
++      spin_unlock_bh(&tt_global->list_lock);
+ }
+ /**