Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -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! */
void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
{
@@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
			continue;
		if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
			continue;
		list_del(&bss->list);
		rb_erase(&bss->rbn, &dev->bss_tree);
		kref_put(&bss->ref, bss_release);
		__cfg80211_unlink_bss(dev, bss);
		expired = true;
	}

@@ -669,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)

	spin_lock_bh(&dev->bss_lock);
	if (!list_empty(&bss->list)) {
		list_del_init(&bss->list);
		__cfg80211_unlink_bss(dev, bss);
		dev->bss_generation++;
		rb_erase(&bss->rbn, &dev->bss_tree);

		kref_put(&bss->ref, bss_release);
	}
	spin_unlock_bh(&dev->bss_lock);
}