Commit 2b78ac9b authored by Juuso Oikarinen's avatar Juuso Oikarinen Committed by John W. Linville

cfg80211: fix BSS double-unlinking (continued)

This patch adds to the fix "fix BSS double-unlinking"
(commit 3207390a) by Johannes Berg.

It turns out, that the double-unlinking scenario can also occur if expired
BSS elements are removed whilst an interface is performing association.

To work around that, replace list_del with list_del_init also in the
"cfg80211_bss_expire" function, so that the check for whether the BSS still is
in the list works correctly in cfg80211_unlink_bss.
Signed-off-by: default avatarJuuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent bef9bacc
...@@ -123,6 +123,15 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, ...@@ -123,6 +123,15 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
} }
} }
/* must hold dev->bss_lock! */
static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
struct cfg80211_internal_bss *bss)
{
list_del_init(&bss->list);
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
}
/* must hold dev->bss_lock! */ /* must hold dev->bss_lock! */
void cfg80211_bss_expire(struct cfg80211_registered_device *dev) void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
{ {
...@@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev) ...@@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
continue; continue;
if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
continue; continue;
list_del(&bss->list); __cfg80211_unlink_bss(dev, bss);
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
expired = true; expired = true;
} }
...@@ -669,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) ...@@ -669,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
spin_lock_bh(&dev->bss_lock); spin_lock_bh(&dev->bss_lock);
if (!list_empty(&bss->list)) { if (!list_empty(&bss->list)) {
list_del_init(&bss->list); __cfg80211_unlink_bss(dev, bss);
dev->bss_generation++; dev->bss_generation++;
rb_erase(&bss->rbn, &dev->bss_tree);
kref_put(&bss->ref, bss_release);
} }
spin_unlock_bh(&dev->bss_lock); spin_unlock_bh(&dev->bss_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment