Patchwork driver_nl80211: use safe list iteration

login
register
mail settings
Submitter Johannes Berg
Date June 1, 2012, 8:45 a.m.
Message ID <1338540337.4884.12.camel@jlt3.sipsolutions.net>
Download mbox | patch
Permalink /patch/162276/
State Accepted
Commit 24b5bd8b42c05ca5c041c88abf3944a07f3f839f
Headers show

Comments

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(-)
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

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);