diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 25e1e1f..dffeaca 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1239,15 +1239,25 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 }
 EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
 
-static void ieee80211_scan_add_ies(struct iw_request_info *info,
-				   const struct cfg80211_bss_ies *ies,
-				   char **current_ev, char *end_buf)
+static inline void cfg80211_buf_full(char *prev_ev,
+				     char *current_ev,
+				     int *err)
+{
+	if (unlikely(prev_ev == current_ev))
+		*err = -E2BIG;
+}
+
+static int ieee80211_scan_add_ies(struct iw_request_info *info,
+				  const struct cfg80211_bss_ies *ies,
+				  char **current_ev, char *end_buf)
 {
 	const u8 *pos, *end, *next;
 	struct iw_event iwe;
+	char *prev_ev;
+	int err = 0;
 
 	if (!ies)
-		return;
+		return err;
 
 	/*
 	 * If needed, fragment the IEs buffer (at IE boundaries) into short
@@ -1264,10 +1274,11 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = IWEVGENIE;
 		iwe.u.data.length = next - pos;
+		prev_ev = *current_ev;
 		*current_ev = iwe_stream_add_point(info, *current_ev,
 						   end_buf, &iwe,
 						   (void *)pos);
-
+		cfg80211_buf_full(prev_ev, *current_ev, &err);
 		pos = next;
 	}
 
@@ -1275,10 +1286,13 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = IWEVGENIE;
 		iwe.u.data.length = end - pos;
+		prev_ev = *current_ev;
 		*current_ev = iwe_stream_add_point(info, *current_ev,
 						   end_buf, &iwe,
 						   (void *)pos);
+		cfg80211_buf_full(prev_ev, *current_ev, &err);
 	}
+	return err;
 }
 
 static char *
@@ -1292,27 +1306,36 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 	u8 *buf, *cfg, *p;
 	int rem, i, sig;
 	bool ismesh = false;
+	char *prev_ev;
+	char *orig_ev = current_ev;
+	int err = 0;
 
 	memset(&iwe, 0, sizeof(iwe));
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
+	prev_ev = current_ev;
 	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
 					  IW_EV_ADDR_LEN);
+	cfg80211_buf_full(prev_ev, current_ev, &err);
 
 	memset(&iwe, 0, sizeof(iwe));
 	iwe.cmd = SIOCGIWFREQ;
 	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
 	iwe.u.freq.e = 0;
+	prev_ev = current_ev;
 	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
 					  IW_EV_FREQ_LEN);
+	cfg80211_buf_full(prev_ev, current_ev, &err);
 
 	memset(&iwe, 0, sizeof(iwe));
 	iwe.cmd = SIOCGIWFREQ;
 	iwe.u.freq.m = bss->pub.channel->center_freq;
 	iwe.u.freq.e = 6;
+	prev_ev = current_ev;
 	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
 					  IW_EV_FREQ_LEN);
+	cfg80211_buf_full(prev_ev, current_ev, &err);
 
 	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
 		memset(&iwe, 0, sizeof(iwe));
@@ -1341,8 +1364,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 			/* not reached */
 			break;
 		}
+		prev_ev = current_ev;
 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 						  &iwe, IW_EV_QUAL_LEN);
+		cfg80211_buf_full(prev_ev, current_ev, &err);
 	}
 
 	memset(&iwe, 0, sizeof(iwe));
@@ -1352,8 +1377,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 	else
 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 	iwe.u.data.length = 0;
+	prev_ev = current_ev;
 	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 					  &iwe, "");
+	cfg80211_buf_full(prev_ev, current_ev, &err);
 
 	rcu_read_lock();
 	ies = rcu_dereference(bss->pub.ies);
@@ -1371,16 +1398,20 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 			iwe.cmd = SIOCGIWESSID;
 			iwe.u.data.length = ie[1];
 			iwe.u.data.flags = 1;
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 							  &iwe, (u8 *)ie + 2);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			break;
 		case WLAN_EID_MESH_ID:
 			memset(&iwe, 0, sizeof(iwe));
 			iwe.cmd = SIOCGIWESSID;
 			iwe.u.data.length = ie[1];
 			iwe.u.data.flags = 1;
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 							  &iwe, (u8 *)ie + 2);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			break;
 		case WLAN_EID_MESH_CONFIG:
 			ismesh = true;
@@ -1395,41 +1426,55 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 			sprintf(buf, "Mesh Network Path Selection Protocol ID: "
 				"0x%02X", cfg[0]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Path Selection Metric ID: 0x%02X",
 				cfg[1]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Congestion Control Mode ID: 0x%02X",
 				cfg[2]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
 			iwe.u.data.length = strlen(buf);
+			prev_ev = current_ev;
 			current_ev = iwe_stream_add_point(info, current_ev,
 							  end_buf,
 							  &iwe, buf);
+			cfg80211_buf_full(prev_ev, current_ev, &err);
 			kfree(buf);
 			break;
 		case WLAN_EID_SUPP_RATES:
@@ -1445,8 +1490,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 			for (i = 0; i < ie[1]; i++) {
 				iwe.u.bitrate.value =
 					((ie[i + 2] & 0x7f) * 500000);
+				prev_ev = p;
 				p = iwe_stream_add_value(info, current_ev, p,
 						end_buf, &iwe, IW_EV_PARAM_LEN);
+				cfg80211_buf_full((u8 *) prev_ev, p, &err);
 			}
 			current_ev = p;
 			break;
@@ -1465,8 +1512,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 			iwe.u.mode = IW_MODE_MASTER;
 		else
 			iwe.u.mode = IW_MODE_ADHOC;
+		prev_ev = current_ev;
 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
 						  &iwe, IW_EV_UINT_LEN);
+		cfg80211_buf_full(prev_ev, current_ev, &err);
 	}
 
 	buf = kmalloc(31, GFP_ATOMIC);
@@ -1475,22 +1524,31 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
 		iwe.cmd = IWEVCUSTOM;
 		sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
 		iwe.u.data.length = strlen(buf);
+		prev_ev = current_ev;
 		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
 						  &iwe, buf);
+		cfg80211_buf_full(prev_ev, current_ev, &err);
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = IWEVCUSTOM;
 		sprintf(buf, " Last beacon: %ums ago",
 			elapsed_jiffies_msecs(bss->ts));
 		iwe.u.data.length = strlen(buf);
+		prev_ev = current_ev;
 		current_ev = iwe_stream_add_point(info, current_ev,
 						  end_buf, &iwe, buf);
+		cfg80211_buf_full(prev_ev, current_ev, &err);
 		kfree(buf);
 	}
 
-	ieee80211_scan_add_ies(info, ies, &current_ev, end_buf);
+	if (!err)
+		err = ieee80211_scan_add_ies(info, ies, &current_ev, end_buf);
+
 	rcu_read_unlock();
 
-	return current_ev;
+	if (err)
+		return orig_ev;
+	else
+		return current_ev;
 }
 
 
@@ -1499,22 +1557,30 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
 				  char *buf, size_t len)
 {
 	char *current_ev = buf;
+	char *prev_ev;
 	char *end_buf = buf + len;
 	struct cfg80211_internal_bss *bss;
+	int err = 0;
 
 	spin_lock_bh(&rdev->bss_lock);
 	cfg80211_bss_expire(rdev);
 
 	list_for_each_entry(bss, &rdev->bss_list, list) {
 		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
-			spin_unlock_bh(&rdev->bss_lock);
-			return -E2BIG;
+			err = -E2BIG;
+			goto out_unlock;
 		}
+		prev_ev = current_ev;
 		current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
 					   current_ev, end_buf);
+		cfg80211_buf_full(prev_ev, current_ev, &err);
 	}
+out_unlock:
 	spin_unlock_bh(&rdev->bss_lock);
-	return current_ev - buf;
+	if (err)
+		return err;
+	else
+		return current_ev - buf;
 }
 
 
