Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 May 2015 22:28:42 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282372 - head/sys/net80211
Message-ID:  <201505032228.t43MSg1P059394@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Sun May  3 22:28:42 2015
New Revision: 282372
URL: https://svnweb.freebsd.org/changeset/base/282372

Log:
  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>

Modified:
  head/sys/net80211/ieee80211_node.c

Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c	Sun May  3 22:13:55 2015	(r282371)
+++ head/sys/net80211/ieee80211_node.c	Sun May  3 22:28:42 2015	(r282372)
@@ -93,6 +93,8 @@ static void node_getmimoinfo(const struc
 
 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_nod
 		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 */
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505032228.t43MSg1P059394>