Blame SOURCES/rh1447073-nl80211-Fix-race-condition-in-detecting-MAC-change.patch

6c9f0c
From 290834df69556b903b49f2a45671cc62b44f13bb Mon Sep 17 00:00:00 2001
6c9f0c
From: Beniamino Galvani <bgalvani@redhat.com>
6c9f0c
Date: Fri, 28 Apr 2017 17:59:30 +0200
6c9f0c
Subject: [PATCH] nl80211: Fix race condition in detecting MAC change
6c9f0c
6c9f0c
Commit 3e0272ca00ce1df35b45e7d739dd7e935f13fd84 ('nl80211: Re-read MAC
6c9f0c
address on RTM_NEWLINK') added the detection of external changes to MAC
6c9f0c
address when the interface is brought up.
6c9f0c
6c9f0c
If the interface state is changed quickly enough, wpa_supplicant may
6c9f0c
receive the netlink message for the !IFF_UP event when the interface
6c9f0c
has already been brought up and would ignore the next netlink IFF_UP
6c9f0c
message, missing the MAC change.
6c9f0c
6c9f0c
Fix this by also reloading the MAC address when a !IFF_UP event is
6c9f0c
received with the interface up, because this implies that the
6c9f0c
interface went down and up again, possibly changing the address.
6c9f0c
6c9f0c
Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
6c9f0c
---
6c9f0c
 src/drivers/driver_nl80211.c | 47 +++++++++++++++++++++++++-------------------
6c9f0c
 1 file changed, 27 insertions(+), 20 deletions(-)
6c9f0c
6c9f0c
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
6c9f0c
index af1cb84..24fad29 100644
6c9f0c
--- a/src/drivers/driver_nl80211.c
6c9f0c
+++ b/src/drivers/driver_nl80211.c
6c9f0c
@@ -933,6 +933,30 @@ nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
6c9f0c
 }
6c9f0c
 
6c9f0c
 
6c9f0c
+static void nl80211_refresh_mac(struct wpa_driver_nl80211_data *drv,
6c9f0c
+				int ifindex)
6c9f0c
+{
6c9f0c
+	struct i802_bss *bss;
6c9f0c
+	u8 addr[ETH_ALEN];
6c9f0c
+
6c9f0c
+	bss = get_bss_ifindex(drv, ifindex);
6c9f0c
+	if (bss &&
6c9f0c
+	    linux_get_ifhwaddr(drv->global->ioctl_sock,
6c9f0c
+			       bss->ifname, addr) < 0) {
6c9f0c
+		wpa_printf(MSG_DEBUG,
6c9f0c
+			   "nl80211: %s: failed to re-read MAC address",
6c9f0c
+			   bss->ifname);
6c9f0c
+	} else if (bss && os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
6c9f0c
+		wpa_printf(MSG_DEBUG,
6c9f0c
+			   "nl80211: Own MAC address on ifindex %d (%s) changed from "
6c9f0c
+			   MACSTR " to " MACSTR,
6c9f0c
+			   ifindex, bss->ifname,
6c9f0c
+			   MAC2STR(bss->addr), MAC2STR(addr));
6c9f0c
+		os_memcpy(bss->addr, addr, ETH_ALEN);
6c9f0c
+	}
6c9f0c
+}
6c9f0c
+
6c9f0c
+
6c9f0c
 static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
6c9f0c
 						 struct ifinfomsg *ifi,
6c9f0c
 						 u8 *buf, size_t len)
6c9f0c
@@ -997,6 +1021,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
6c9f0c
 		namebuf[0] = '\0';
6c9f0c
 		if (if_indextoname(ifi->ifi_index, namebuf) &&
6c9f0c
 		    linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
6c9f0c
+			/* Re-read MAC address as it may have changed */
6c9f0c
+			nl80211_refresh_mac(drv, ifi->ifi_index);
6c9f0c
 			wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
6c9f0c
 				   "event since interface %s is up", namebuf);
6c9f0c
 			drv->ignore_if_down_event = 0;
6c9f0c
@@ -1044,27 +1070,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
6c9f0c
 				   "event since interface %s is marked "
6c9f0c
 				   "removed", drv->first_bss->ifname);
6c9f0c
 		} else {
6c9f0c
-			struct i802_bss *bss;
6c9f0c
-			u8 addr[ETH_ALEN];
6c9f0c
-
6c9f0c
 			/* Re-read MAC address as it may have changed */
6c9f0c
-			bss = get_bss_ifindex(drv, ifi->ifi_index);
6c9f0c
-			if (bss &&
6c9f0c
-			    linux_get_ifhwaddr(drv->global->ioctl_sock,
6c9f0c
-					       bss->ifname, addr) < 0) {
6c9f0c
-				wpa_printf(MSG_DEBUG,
6c9f0c
-					   "nl80211: %s: failed to re-read MAC address",
6c9f0c
-					   bss->ifname);
6c9f0c
-			} else if (bss &&
6c9f0c
-				   os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
6c9f0c
-				wpa_printf(MSG_DEBUG,
6c9f0c
-					   "nl80211: Own MAC address on ifindex %d (%s) changed from "
6c9f0c
-					   MACSTR " to " MACSTR,
6c9f0c
-					   ifi->ifi_index, bss->ifname,
6c9f0c
-					   MAC2STR(bss->addr),
6c9f0c
-					   MAC2STR(addr));
6c9f0c
-				os_memcpy(bss->addr, addr, ETH_ALEN);
6c9f0c
-			}
6c9f0c
+			nl80211_refresh_mac(drv, ifi->ifi_index);
6c9f0c
 
6c9f0c
 			wpa_printf(MSG_DEBUG, "nl80211: Interface up");
6c9f0c
 			drv->if_disabled = 0;
6c9f0c
-- 
6c9f0c
2.9.3
6c9f0c