57 lines
2.1 KiB
Diff
57 lines
2.1 KiB
Diff
From: Sven Eckelmann <sven@narfation.org>
|
|
Date: Thu, 6 Sep 2018 14:35:27 +0200
|
|
Subject: 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
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|