mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-04 18:18:54 +00:00
batman-adv: Fix list removal of batadv_hardif_neigh_node
The neigh_list with batadv_hardif_neigh_node objects is accessed with only rcu_read_lock in batadv_hardif_neigh_get and batadv_iv_neigh_print. Thus it is not allowed to kfree the object before the rcu grace period ends (which may still protects context accessing this object). Therefore the object has first to be removed from the neigh_list and then it has either wait with synchronize_rcu or call_rcu till the grace period ends before it can be freed. Fixes: cef63419f7db ("batman-adv: add list of unique single hop neighbors per hard-interface") Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> Signed-off-by: Antonio Quartulli <a@unstable.cc>
This commit is contained in:
parent
af63cf51b7
commit
bab7c6c3de
@ -211,10 +211,6 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
|
||||
|
||||
hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu);
|
||||
|
||||
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
hlist_del_init_rcu(&hardif_neigh->list);
|
||||
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
|
||||
batadv_hardif_free_ref_now(hardif_neigh->if_incoming);
|
||||
kfree(hardif_neigh);
|
||||
}
|
||||
@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
|
||||
static void
|
||||
batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
{
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount))
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount)) {
|
||||
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
hlist_del_init_rcu(&hardif_neigh->list);
|
||||
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
|
||||
batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
*/
|
||||
void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
{
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount))
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount)) {
|
||||
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
hlist_del_init_rcu(&hardif_neigh->list);
|
||||
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
|
||||
call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user