aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2018-08-12 15:04:44 -0400
committerSimon Wunderlich <sw@simonwunderlich.de>2018-09-06 08:37:12 -0400
commite7136e48ffdfb9f37b0820f619380485eb407361 (patch)
tree1e50173ed02b2569a93b9214a24ec9807784dd30
parent94cb82f594ed86be303398d6dfc7640a6f1d45d4 (diff)
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: d657e621a0f5 ("batman-adv: add reference counting for type batadv_tt_orig_list_entry") Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
-rw-r--r--net/batman-adv/translation-table.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 12a2b7d21376..d21624c44665 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1613,6 +1613,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1613{ 1613{
1614 struct batadv_tt_orig_list_entry *orig_entry; 1614 struct batadv_tt_orig_list_entry *orig_entry;
1615 1615
1616 spin_lock_bh(&tt_global->list_lock);
1617
1616 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); 1618 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
1617 if (orig_entry) { 1619 if (orig_entry) {
1618 /* refresh the ttvn: the current value could be a bogus one that 1620 /* refresh the ttvn: the current value could be a bogus one that
@@ -1635,11 +1637,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1635 orig_entry->flags = flags; 1637 orig_entry->flags = flags;
1636 kref_init(&orig_entry->refcount); 1638 kref_init(&orig_entry->refcount);
1637 1639
1638 spin_lock_bh(&tt_global->list_lock);
1639 kref_get(&orig_entry->refcount); 1640 kref_get(&orig_entry->refcount);
1640 hlist_add_head_rcu(&orig_entry->list, 1641 hlist_add_head_rcu(&orig_entry->list,
1641 &tt_global->orig_list); 1642 &tt_global->orig_list);
1642 spin_unlock_bh(&tt_global->list_lock);
1643 atomic_inc(&tt_global->orig_list_count); 1643 atomic_inc(&tt_global->orig_list_count);
1644 1644
1645sync_flags: 1645sync_flags:
@@ -1647,6 +1647,8 @@ sync_flags:
1647out: 1647out:
1648 if (orig_entry) 1648 if (orig_entry)
1649 batadv_tt_orig_list_entry_put(orig_entry); 1649 batadv_tt_orig_list_entry_put(orig_entry);
1650
1651 spin_unlock_bh(&tt_global->list_lock);
1650} 1652}
1651 1653
1652/** 1654/**