Remove old iv_bss entry from the node table

This may happen on RUN -> SCAN -> RUN -> SCAN state transition:

1. RUN -> SCAN: in ieee80211_sta_join1(): iv_bss will be moved to obss,
   refcnt will be reduced by 2 (default minimum).

Now, if old iv_bss have some extra references (for example, from
unacknowledged probe responses), it will not be freed and will stay
in the node table.

2. SCAN -> RUN.

3. If old iv_bss will not be deleted by the time when the next RUN -> SCAN
   state transition occurs, then sta_leave() will reduce it's reference
   counter once more. As a result, two last users will free it -> this will
   lead to kernel panic.

In this patch old iv_bss entry is explicitly removed from the node table in
ieee80211_sta_join1() (as a result, it will not be processed by sta_leave()).

PR:		kern/199676
Differential Revision:	Andriy Voskoboinyk <s3erios@gmail.com>
This commit is contained in:
Adrian Chadd 2015-05-03 22:28:42 +00:00
parent 6b997e0c7d
commit 8a0558317e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282372

View File

@ -93,6 +93,8 @@ static void node_getmimoinfo(const struct ieee80211_node *,
static void _ieee80211_free_node(struct ieee80211_node *);
static void node_reclaim(struct ieee80211_node_table *nt,
struct ieee80211_node *ni);
static void ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt, const char *name,
int inact, int keymaxix);
@ -719,9 +721,15 @@ ieee80211_sta_join1(struct ieee80211_node *selbs)
IEEE80211_ADDR_EQ(obss->ni_macaddr, selbs->ni_macaddr));
vap->iv_bss = selbs; /* NB: caller assumed to bump refcnt */
if (obss != NULL) {
struct ieee80211_node_table *nt = obss->ni_table;
copy_bss(selbs, obss);
ieee80211_node_decref(obss); /* iv_bss reference */
ieee80211_free_node(obss); /* station table reference */
IEEE80211_NODE_LOCK(nt);
node_reclaim(nt, obss); /* station table reference */
IEEE80211_NODE_UNLOCK(nt);
obss = NULL; /* NB: guard against later use */
}