mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 12:35:52 +02:00
batman-adv: bla: only purge non-released claims
When batadv_bla_purge_claims() goes through the list of claims, it is only
traversing the hash list with an rcu_read_lock(). Due to a potential
parallel batadv_claim_put(), it can happen that it encounters a claim which
was actually in the process of being released+freed by
batadv_claim_release(). In this case, backbone_gw is set to NULL before the
delayed RCU kfree is started. Calling batadv_bla_claim_get_backbone_gw() is
then no longer allowed because it would cause a NULL-ptr derefence.
To avoid this, only claims with a valid reference counter must be purged.
All others are already taken care of.
Cc: stable@kernel.org
Fixes: 23721387c4 ("batman-adv: add basic bridge loop avoidance code")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
This commit is contained in:
parent
4ae1709a31
commit
cf6b604011
|
|
@ -1288,6 +1288,13 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
|
|||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(claim, head, hash_entry) {
|
||||
/* only purge claims not currently in the process of being released.
|
||||
* Such claims could otherwise have a NULL-ptr backbone_gw set because
|
||||
* they already went through batadv_claim_release()
|
||||
*/
|
||||
if (!kref_get_unless_zero(&claim->refcount))
|
||||
continue;
|
||||
|
||||
backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
|
||||
if (now)
|
||||
goto purge_now;
|
||||
|
|
@ -1313,6 +1320,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
|
|||
claim->addr, claim->vid);
|
||||
skip:
|
||||
batadv_backbone_gw_put(backbone_gw);
|
||||
batadv_claim_put(claim);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user