driver_nl80211: use safe list iteration

Submitted by Johannes Berg on June 1, 2012, 8:45 a.m.

Details

Message ID 1338540337.4884.12.camel@jlt3.sipsolutions.net
State Accepted
Commit 24b5bd8b42c05ca5c041c88abf3944a07f3f839f
Headers show

Commit Message

Johannes Berg June 1, 2012, 8:45 a.m.
From: Johannes Berg <johannes.berg@intel.com>

In certain cases like PBC session overlap it
appears to be possible that an interface is
removed due to an event handled on it, this
leads to list corruption. Use safe iteration
to prevent this issue.

Reported-by: Nirav Shah <nirav.j2.shah@intel.com>
Reported-by: Neeraj Kumar Garg <neerajkg@broadcom.com>
Signed-hostap: Johannes Berg <johannes.berg@intel.com>
intended-for: hostap-1
---
 src/drivers/driver_nl80211.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Jouni Malinen June 4, 2012, 5:27 p.m.
On Fri, Jun 01, 2012 at 10:45:37AM +0200, Johannes Berg wrote:
> In certain cases like PBC session overlap it
> appears to be possible that an interface is
> removed due to an event handled on it, this
> leads to list corruption. Use safe iteration
> to prevent this issue.

Thanks, applied.

Patch hide | download patch | download mbox

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 693a885..92a7de0 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2198,7 +2198,7 @@  static int process_global_event(struct nl_msg *msg, void *arg)
 	struct nl80211_global *global = arg;
 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct wpa_driver_nl80211_data *drv;
+	struct wpa_driver_nl80211_data *drv, *tmp;
 	int ifidx = -1;
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -2207,8 +2207,8 @@  static int process_global_event(struct nl_msg *msg, void *arg)
 	if (tb[NL80211_ATTR_IFINDEX])
 		ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
 
-	dl_list_for_each(drv, &global->interfaces,
-			 struct wpa_driver_nl80211_data, list) {
+	dl_list_for_each_safe(drv, tmp, &global->interfaces,
+			      struct wpa_driver_nl80211_data, list) {
 		if (ifidx == -1 || ifidx == drv->ifindex ||
 		    have_ifidx(drv, ifidx))
 			do_process_drv_event(drv, gnlh->cmd, tb);