Skip to content

Commit ae3cdc9

Browse files
ecsvsimonwunderlich
authored andcommitted
batman-adv: Prevent duplicated tvlv handler
The function batadv_tvlv_handler_register is responsible for adding new tvlv_handler to the handler_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: ef26157 ("batman-adv: tvlv - basic infrastructure") Signed-off-by: Sven Eckelmann <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent e7136e4 commit ae3cdc9

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

net/batman-adv/tvlv.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
529529
{
530530
struct batadv_tvlv_handler *tvlv_handler;
531531

532+
spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
533+
532534
tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
533535
if (tvlv_handler) {
536+
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
534537
batadv_tvlv_handler_put(tvlv_handler);
535538
return;
536539
}
537540

538541
tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
539-
if (!tvlv_handler)
542+
if (!tvlv_handler) {
543+
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
540544
return;
545+
}
541546

542547
tvlv_handler->ogm_handler = optr;
543548
tvlv_handler->unicast_handler = uptr;
@@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
547552
kref_init(&tvlv_handler->refcount);
548553
INIT_HLIST_NODE(&tvlv_handler->list);
549554

550-
spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
551555
kref_get(&tvlv_handler->refcount);
552556
hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
553557
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);

0 commit comments

Comments
 (0)