Merge "Android: binder: check set_context_mgr permission on time." into android-chromeos-dragon-3.18
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index 111fbe6..2cdcc99 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -1069,14 +1069,17 @@
 		nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x00000008);
 
 	if (show) {
-		nv_error(priv, "PBDMA%d:", unit);
-		nvkm_bitfield_print(gk104_fifo_pbdma_intr_0, show);
-		pr_cont("\n");
-		nv_error(priv,
-			 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
-			 unit, chid,
-			 nvkm_client_name_for_fifo_chid(&priv->base, chid),
-			 subc, mthd, data);
+		static unsigned long int j;
+		if (printk_timed_ratelimit(&j, 1000)) {
+			nv_error(priv, "PBDMA%d:", unit);
+			nvkm_bitfield_print(gk104_fifo_pbdma_intr_0, show);
+			pr_cont("\n");
+			nv_error(priv,
+				 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
+				 unit, chid,
+				 nvkm_client_name_for_fifo_chid(&priv->base, chid),
+				 subc, mthd, data);
+		}
 		nvkm_fifo_eevent(&priv->base, chid,
 				NOUVEAU_GEM_CHANNEL_PBDMA_ERROR);
 	}
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index fd03558..c8e39f6 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -8207,6 +8207,7 @@
 	return err;
 }
 
+#ifdef DHD_ANQPO_SUPPORT
 void * dhd_dev_process_anqpo_result(struct net_device *dev,
 			const void  *data, uint32 event, int *send_evt_bytes)
 {
@@ -8214,6 +8215,7 @@
 
 	return (dhd_pno_process_anqpo_result(&dhd->pub, data, event, send_evt_bytes));
 }
+#endif /* DHD_ANQPO_SUPPORT */
 #endif /* GSCAN_SUPPORT */
 
 int dhd_dev_set_rssi_monitor_cfg(struct net_device *dev, int start,
diff --git a/drivers/net/wireless/bcmdhd/dhd_msgbuf.c b/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
index 8d7d4bf..e6e2848 100644
--- a/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
+++ b/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
@@ -2493,22 +2493,24 @@
 dhdmsgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
 {
 	dhd_prot_t *prot = dhd->prot;
-
 	int ret = 0;
 
-	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-
-	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
-	if (cmd == WLC_GET_VAR && buf)
-	{
-		if (!strcmp((char *)buf, "bcmerrorstr"))
-		{
-			strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN);
+	DHD_TRACE(("%s: Enter\n", __func__));
+	if (!buf || !len) {
+		DHD_ERROR(("%s(): Zero length bailing\n", __func__));
+		ret = BCME_BADARG;
+		goto done;
+	}
+	if (cmd == WLC_GET_VAR) {
+		/* Respond "bcmerror" and "bcmerrorstr" with local cache */
+		if ((len > strlen("bcmerrorstr")) &&
+		    !strcmp(buf, "bcmerrorstr")) {
+			strlcpy(buf, bcmerrorstr(dhd->dongle_error), len);
 			goto done;
-		}
-		else if (!strcmp((char *)buf, "bcmerror"))
-		{
-			*(int *)buf = dhd->dongle_error;
+		} else if ((len > strlen("bcmerror")) &&
+			   !strcmp(buf, "bcmerror")) {
+			memcpy(buf, &dhd->dongle_error,
+			       sizeof(dhd->dongle_error));
 			goto done;
 		}
 	}
diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.c b/drivers/net/wireless/bcmdhd/dhd_pno.c
index 049bd71..53c87cb 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pno.c
+++ b/drivers/net/wireless/bcmdhd/dhd_pno.c
@@ -3824,6 +3824,7 @@
 	return results;
 }
 
+#ifdef DHD_ANQPO_SUPPORT
 void *
 dhd_pno_process_anqpo_result(dhd_pub_t *dhd, const void *data, uint32 event, int *size)
 {
@@ -3874,7 +3875,7 @@
 
 	return result;
 }
-
+#endif /* DHD_ANQPO_SUPPORT */
 
 void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes,
       hotlist_type_t type)
diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.h b/drivers/net/wireless/bcmdhd/dhd_pno.h
index 349cee8..ad9e1a8 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pno.h
+++ b/drivers/net/wireless/bcmdhd/dhd_pno.h
@@ -98,7 +98,8 @@
 #define CHANNEL_BUCKET_EMPTY_INDEX                      0xFFFF
 #define GSCAN_RETRY_THRESHOLD              3
 #define MAX_EPNO_SSID_NUM                   32
-
+#define GSCAN_ANQPO_MAX_HS_LIST_SIZE	16
+#define ANQPO_MAX_HS_NAI_REALM_SIZE		256
 #endif /* GSCAN_SUPPORT */
 
 enum scan_status {
@@ -350,10 +351,10 @@
 } gscan_results_cache_t;
 
 typedef struct {
-    int  id;                            /* identifier of this network block, report this in event */
-    char realm[256];                    /* null terminated UTF8 encoded realm, 0 if unspecified */
-    int64_t roamingConsortiumIds[16];   /* roaming consortium ids to match, 0s if unspecified */
-    uint8 plmn[3];                      /* mcc/mnc combination as per rules, 0s if unspecified */
+	int  id;
+	char realm[ANQPO_MAX_HS_NAI_REALM_SIZE];
+	int64_t roamingConsortiumIds[ANQPO_MAX_PFN_HS];
+	uint8 plmn[ANQPO_MCC_LENGTH];
 } wifi_passpoint_network;
 
 typedef struct dhd_pno_gscan_capabilities {
@@ -517,8 +518,10 @@
 extern int dhd_dev_wait_batch_results_complete(struct net_device *dev);
 extern void * dhd_dev_process_epno_result(struct net_device *dev,
                         const void  *data, uint32 event, int *send_evt_bytes);
+#ifdef DHD_ANQPO_SUPPORT
 extern void * dhd_dev_process_anqpo_result(struct net_device *dev,
 			const void  *data, uint32 event, int *send_evt_bytes);
+#endif /* DHD_ANQPO_SUPPORT */
 #endif /* GSCAN_SUPPORT */
 /* dhd pno fuctions */
 extern int dhd_pno_stop_for_ssid(dhd_pub_t *dhd);
@@ -565,7 +568,9 @@
 extern int dhd_wait_batch_results_complete(dhd_pub_t *dhd);
 extern void * dhd_pno_process_epno_result(dhd_pub_t *dhd, const void *data,
          uint32 event, int *size);
+#ifdef DHD_ANQPO_SUPPORT
 extern void * dhd_pno_process_anqpo_result(dhd_pub_t *dhd, const void *data, uint32 event, int *size);
+#endif /* DHD_ANQPO_SUPPORT */
 #endif /* GSCAN_SUPPORT */
 #endif /* PNO_SUPPORT */
 
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 24b71c5..0db69ef 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -246,11 +246,18 @@
 		return -1;
 	if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) {
 		DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__));
+	} else if (total_len <= ssid.SSID_len) {
+		return -ENOMEM;
 	} else {
 		memcpy(command, ssid.SSID, ssid.SSID_len);
 		bytes_written = ssid.SSID_len;
 	}
-	bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi);
+	if ((total_len - bytes_written) < (strlen(" rssi -XXX") + 1))
+		return -ENOMEM;
+	bytes_written += scnprintf(&command[bytes_written],
+		total_len - bytes_written, " rssi %d", rssi);
+	command[bytes_written] = '\0';
+
 	DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written));
 	return bytes_written;
 }
@@ -1284,10 +1291,13 @@
 int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
 {
 #define PRIVATE_COMMAND_MAX_LEN	8192
+#define PRIVATE_COMMAND_DEF_LEN	4096
+
 	int ret = 0;
 	char *command = NULL;
 	int bytes_written = 0;
 	android_wifi_priv_cmd priv_cmd;
+	int buf_size = 0;
 
 	net_os_wake_lock(net);
 
@@ -1321,12 +1331,17 @@
 			goto exit;
 		}
 	}
+
 	if ((priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) || (priv_cmd.total_len < 0)) {
-		DHD_ERROR(("%s: too long priavte command\n", __FUNCTION__));
+		DHD_ERROR(("%s: buf length invalid:%d\n", __FUNCTION__,
+			   priv_cmd.total_len));
 		ret = -EINVAL;
 		goto exit;
 	}
-	command = kmalloc((priv_cmd.total_len + 1), GFP_KERNEL);
+
+	buf_size = max(priv_cmd.total_len, PRIVATE_COMMAND_DEF_LEN);
+	command = kmalloc((buf_size + 1), GFP_KERNEL);
+
 	if (!command)
 	{
 		DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__));
@@ -1341,6 +1356,41 @@
 
 	DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name));
 
+	bytes_written = wl_handle_private_cmd(net, command, priv_cmd.total_len);
+	if (bytes_written >= 0) {
+		if ((bytes_written == 0) && (priv_cmd.total_len > 0))
+			command[0] = '\0';
+		if (bytes_written >= priv_cmd.total_len) {
+			DHD_ERROR(("%s: err. b_w:%d >= tot:%d\n", __FUNCTION__,
+				   bytes_written, priv_cmd.total_len));
+			ret = BCME_BUFTOOSHORT;
+			goto exit;
+		}
+		bytes_written++;
+		priv_cmd.used_len = bytes_written;
+		if (copy_to_user(priv_cmd.buf, command, bytes_written)) {
+			DHD_ERROR(("%s: failed copy to user\n", __FUNCTION__));
+			ret = -EFAULT;
+		}
+	} else {
+		ret = bytes_written;
+	}
+
+exit:
+	net_os_wake_unlock(net);
+	kfree(command);
+	return ret;
+}
+
+int
+wl_handle_private_cmd(struct net_device *net, char *command, u32 buf_size)
+{
+	int bytes_written = 0;
+	android_wifi_priv_cmd priv_cmd;
+
+	bzero(&priv_cmd, sizeof(android_wifi_priv_cmd));
+	priv_cmd.total_len = buf_size;
+
 	if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) {
 		DHD_INFO(("%s, Received regular START command\n", __FUNCTION__));
 		bytes_written = wl_android_wifi_on(net);
@@ -1350,10 +1400,9 @@
 	}
 
 	if (!g_wifi_on) {
-		DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n",
-			__FUNCTION__, command, ifr->ifr_name));
-		ret = 0;
-		goto exit;
+		DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface is down\n",
+			   __FUNCTION__, command));
+		return 0;
 	}
 
 	if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
@@ -1511,36 +1560,10 @@
 	}
 	else {
 		DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
-		snprintf(command, 3, "OK");
-		bytes_written = strlen("OK");
+		bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL");
 	}
 
-	if (bytes_written >= 0) {
-		if ((bytes_written == 0) && (priv_cmd.total_len > 0))
-			command[0] = '\0';
-		if (bytes_written >= priv_cmd.total_len) {
-			DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
-			bytes_written = priv_cmd.total_len;
-		} else {
-			bytes_written++;
-		}
-		priv_cmd.used_len = bytes_written;
-		if (copy_to_user(priv_cmd.buf, command, bytes_written)) {
-			DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__));
-			ret = -EFAULT;
-		}
-	}
-	else {
-		ret = bytes_written;
-	}
-
-exit:
-	net_os_wake_unlock(net);
-	if (command) {
-		kfree(command);
-	}
-
-	return ret;
+	return bytes_written;
 }
 
 int wl_android_init(void)
diff --git a/drivers/net/wireless/bcmdhd/wl_android.h b/drivers/net/wireless/bcmdhd/wl_android.h
index 2827132..f62b646 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.h
+++ b/drivers/net/wireless/bcmdhd/wl_android.h
@@ -53,6 +53,7 @@
 int wl_android_wifi_on(struct net_device *dev);
 int wl_android_wifi_off(struct net_device *dev, bool on_failure);
 int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
+int wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
 
 
 /* hostap mac mode */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 96cceac..8acdfc6 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -9240,6 +9240,7 @@
 			} else
 				err = -ENOMEM;
 			break;
+#ifdef DHD_ANQPO_SUPPORT
 		case WLC_E_PFN_NET_FOUND:
 			ptr = dhd_dev_process_anqpo_result(ndev, data, event, &len);
 			if (ptr) {
@@ -9249,6 +9250,7 @@
 			} else
 				err = -ENOMEM;
 			break;
+#endif /* DHD_ANQPO_SUPPORT */
 		default:
 			WL_ERR(("Unknown event %d\n", event));
 			break;
@@ -9796,7 +9798,9 @@
 	cfg->evt_handler[WLC_E_PFN_BSSID_NET_FOUND] = wl_notify_gscan_event;
 	cfg->evt_handler[WLC_E_PFN_BSSID_NET_LOST] = wl_notify_gscan_event;
 	cfg->evt_handler[WLC_E_PFN_SSID_EXT] = wl_notify_gscan_event;
+#ifdef DHD_ANQPO_SUPPORT
 	cfg->evt_handler[WLC_E_GAS_FRAGMENT_RX] = wl_notify_gscan_event;
+#endif /* DHD_ANQPO_SUPPORT */
 	cfg->evt_handler[WLC_E_ROAM_EXP_EVENT] = wl_handle_roam_exp_event;
 #endif /* GSCAN_SUPPORT */
 	cfg->evt_handler[WLC_E_RSSI_LQM] = wl_handle_rssi_monitor_event;
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
index 1000ec9..5622620 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
@@ -508,23 +508,113 @@
 	return err;
 }
 
-static int wl_cfgvendor_set_scan_cfg(struct wiphy *wiphy,
-	struct wireless_dev *wdev, const void  *data, int len)
+static int
+wl_cfgvendor_set_scan_cfg_bucket(const struct nlattr *prev,
+				 gscan_scan_params_t *scan_param, int num)
+{
+	struct dhd_pno_gscan_channel_bucket  *ch_bucket;
+	int k = 0;
+	int type, err = 0, rem;
+	const struct nlattr *cur, *next;
+
+	nla_for_each_nested(cur, prev, rem) {
+		type = nla_type(cur);
+		ch_bucket = scan_param->channel_bucket;
+		switch (type) {
+		case GSCAN_ATTRIBUTE_BUCKET_ID:
+			break;
+		case GSCAN_ATTRIBUTE_BUCKET_PERIOD:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+
+			ch_bucket[num].bucket_freq_multiple =
+				nla_get_u32(cur) / MSEC_PER_SEC;
+			break;
+		case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			ch_bucket[num].num_channels = nla_get_u32(cur);
+			if (ch_bucket[num].num_channels >
+				GSCAN_MAX_CHANNELS_IN_BUCKET) {
+				WL_DBG(("channel range:%d,bucket:%d\n",
+					ch_bucket[num].num_channels,
+					num));
+				err = -EINVAL;
+				goto exit;
+			}
+			break;
+		case GSCAN_ATTRIBUTE_BUCKET_CHANNELS:
+			nla_for_each_nested(next, cur, rem) {
+				if (k >= GSCAN_MAX_CHANNELS_IN_BUCKET)
+					break;
+				if (nla_len(next) != sizeof(uint32)) {
+					err = -EINVAL;
+					goto exit;
+				}
+				ch_bucket[num].chan_list[k] = nla_get_u32(next);
+				k++;
+			}
+			break;
+		case GSCAN_ATTRIBUTE_BUCKETS_BAND:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			ch_bucket[num].band = (uint16)nla_get_u32(cur);
+			break;
+		case GSCAN_ATTRIBUTE_REPORT_EVENTS:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			ch_bucket[num].report_flag = (uint8)nla_get_u32(cur);
+			break;
+		case GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			ch_bucket[num].repeat = (uint16)nla_get_u32(cur);
+			break;
+		case GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD:
+			if (nla_len(cur) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			ch_bucket[num].bucket_max_multiple =
+				nla_get_u32(cur) / MSEC_PER_SEC;
+			break;
+		default:
+			WL_DBG(("unknown attr type:%d\n", type));
+			err = -EINVAL;
+			goto exit;
+		}
+	}
+
+exit:
+	return err;
+}
+
+static int
+wl_cfgvendor_set_scan_cfg(struct wiphy *wiphy, struct wireless_dev *wdev,
+			  const void  *data, int len)
 {
 	int err = 0;
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 	gscan_scan_params_t *scan_param;
 	int j = 0;
-	int type, tmp, tmp1, tmp2, k = 0;
-	const struct nlattr *iter, *iter1, *iter2;
-	struct dhd_pno_gscan_channel_bucket  *ch_bucket;
+	int type, tmp;
+	const struct nlattr *iter;
 
 	scan_param = kzalloc(sizeof(gscan_scan_params_t), GFP_KERNEL);
 	if (!scan_param) {
 		WL_ERR(("Could not set GSCAN scan cfg, mem alloc failure\n"));
 		err = -EINVAL;
 		return err;
-
 	}
 
 	scan_param->scan_fr = PNO_SCAN_MIN_FW_SEC;
@@ -535,77 +625,60 @@
 			break;
 
 		switch (type) {
-			case GSCAN_ATTRIBUTE_BASE_PERIOD:
-				scan_param->scan_fr = nla_get_u32(iter)/1000;
-				break;
-			case GSCAN_ATTRIBUTE_NUM_BUCKETS:
-				scan_param->nchannel_buckets = nla_get_u32(iter);
-				break;
-			case GSCAN_ATTRIBUTE_CH_BUCKET_1:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_2:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_3:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_4:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_5:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_6:
-			case GSCAN_ATTRIBUTE_CH_BUCKET_7:
-				nla_for_each_nested(iter1, iter, tmp1) {
-					type = nla_type(iter1);
-					ch_bucket =
-					scan_param->channel_bucket;
+		case GSCAN_ATTRIBUTE_BASE_PERIOD:
+			if (nla_len(iter) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			scan_param->scan_fr = nla_get_u32(iter) / MSEC_PER_SEC;
+			break;
+		case GSCAN_ATTRIBUTE_NUM_BUCKETS:
+			if (nla_len(iter) != sizeof(uint32)) {
+				err = -EINVAL;
+				goto exit;
+			}
+			scan_param->nchannel_buckets = nla_get_u32(iter);
+			if (scan_param->nchannel_buckets >=
+			    GSCAN_MAX_CH_BUCKETS) {
+				WL_DBG(("ncha_buck out of range %d\n",
+					scan_param->nchannel_buckets));
+				err = -EINVAL;
+				goto exit;
+			}
+			break;
+		case GSCAN_ATTRIBUTE_CH_BUCKET_1:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_2:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_3:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_4:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_5:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_6:
+		case GSCAN_ATTRIBUTE_CH_BUCKET_7:
+			err = wl_cfgvendor_set_scan_cfg_bucket(iter,
+							       scan_param, j);
+			if (err < 0) {
+				WL_DBG(("set_scan_cfg_buck error:%d\n", err));
+				goto exit;
+			}
 
-					switch (type) {
-						case GSCAN_ATTRIBUTE_BUCKET_ID:
-						break;
-						case GSCAN_ATTRIBUTE_BUCKET_PERIOD:
-							ch_bucket[j].bucket_freq_multiple =
-							    nla_get_u32(iter1)/1000;
-							break;
-						case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS:
-							ch_bucket[j].num_channels =
-							     nla_get_u32(iter1);
-							break;
-						case GSCAN_ATTRIBUTE_BUCKET_CHANNELS:
-							nla_for_each_nested(iter2, iter1, tmp2) {
-								if (k >= GSCAN_MAX_CHANNELS_IN_BUCKET)
-									break;
-								ch_bucket[j].chan_list[k] =
-								     nla_get_u32(iter2);
-								k++;
-							}
-							k = 0;
-							break;
-						case GSCAN_ATTRIBUTE_BUCKETS_BAND:
-							ch_bucket[j].band = (uint16)
-							     nla_get_u32(iter1);
-							break;
-						case GSCAN_ATTRIBUTE_REPORT_EVENTS:
-							ch_bucket[j].report_flag = (uint8)
-							     nla_get_u32(iter1);
-							break;
-						case GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT:
-							ch_bucket[j].repeat = (uint16)
-							     nla_get_u32(iter1);
-							break;
-						case GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD:
-							ch_bucket[j].bucket_max_multiple =
-							     nla_get_u32(iter1)/1000;
-							break;
-					}
-				}
-				j++;
-				break;
+			j++;
+			break;
+		default:
+			WL_DBG(("Unknown attr type %d\n", type));
+			err = -EINVAL;
+			goto exit;
 		}
 	}
 
-	if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg),
-	     DHD_PNO_SCAN_CFG_ID, scan_param, 0) < 0) {
-		WL_ERR(("Could not set GSCAN scan cfg\n"));
+	err = dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg),
+					DHD_PNO_SCAN_CFG_ID, scan_param, 0);
+	if (err < 0) {
+		WL_ERR(("Could not set GSCAN scan cfg error %d\n", err));
 		err = -EINVAL;
 	}
 
+exit:
 	kfree(scan_param);
 	return err;
-
 }
 
 static int wl_cfgvendor_hotlist_cfg(struct wiphy *wiphy,
@@ -615,14 +688,22 @@
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 	gscan_hotlist_scan_params_t *hotlist_params;
 	int tmp, tmp1, tmp2, type, j = 0, dummy;
-	const struct nlattr *outer, *inner, *iter;
+	const struct nlattr *outer, *inner = NULL, *iter;
 	uint8 flush = 0;
 	struct bssid_t *pbssid;
 
-	hotlist_params = (gscan_hotlist_scan_params_t *)kzalloc(len, GFP_KERNEL);
+	if (len < sizeof(*hotlist_params) || len >= WLC_IOCTL_MAXLEN) {
+		WL_ERR(("buffer length :%d wrong - bail out.\n", len));
+		return -EINVAL;
+	}
+
+	hotlist_params = kzalloc(sizeof(*hotlist_params)
+		+ (sizeof(struct bssid_t) * (PFN_SWC_MAX_NUM_APS - 1)),
+		GFP_KERNEL);
+
 	if (!hotlist_params) {
 		WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len));
-		return -1;
+		return -ENOMEM;
 	}
 
 	hotlist_params->lost_ap_window = GSCAN_LOST_AP_WINDOW_DEFAULT;
@@ -630,37 +711,78 @@
 	nla_for_each_attr(iter, data, len, tmp2) {
 		type = nla_type(iter);
 		switch (type) {
-			case GSCAN_ATTRIBUTE_HOTLIST_BSSIDS:
-				pbssid = hotlist_params->bssid;
-				nla_for_each_nested(outer, iter, tmp) {
-					nla_for_each_nested(inner, outer, tmp1) {
-						type = nla_type(inner);
+		case GSCAN_ATTRIBUTE_HOTLIST_BSSIDS:
+			pbssid = hotlist_params->bssid;
+			nla_for_each_nested(outer, iter, tmp) {
+				nla_for_each_nested(inner, outer, tmp1) {
+					type = nla_type(inner);
 
-						switch (type) {
-							case GSCAN_ATTRIBUTE_BSSID:
-								memcpy(&(pbssid[j].macaddr),
-								  nla_data(inner), ETHER_ADDR_LEN);
-								break;
-							case GSCAN_ATTRIBUTE_RSSI_LOW:
-								pbssid[j].rssi_reporting_threshold =
-								         (int8) nla_get_u8(inner);
-								break;
-							case GSCAN_ATTRIBUTE_RSSI_HIGH:
-								dummy = (int8) nla_get_u8(inner);
-								break;
+					switch (type) {
+					case GSCAN_ATTRIBUTE_BSSID:
+						if (nla_len(inner) != sizeof(pbssid[j].macaddr)) {
+							WL_DBG(("type:%d length:%d not matching.\n",
+								type, nla_len(inner)));
+							err = -EINVAL;
+							goto exit;
 						}
+						memcpy(
+							&pbssid[j].macaddr,
+							nla_data(inner),
+							sizeof(pbssid[j].macaddr));
+						break;
+					case GSCAN_ATTRIBUTE_RSSI_LOW:
+						if (nla_len(inner) != sizeof(uint8)) {
+							WL_DBG(("type:%d length:%d not matching.\n",
+								type, nla_len(inner)));
+							err = -EINVAL;
+							goto exit;
+						}
+						pbssid[j].rssi_reporting_threshold =
+								(int8)nla_get_u8(inner);
+						break;
+					case GSCAN_ATTRIBUTE_RSSI_HIGH:
+						if (nla_len(inner) != sizeof(uint8)) {
+							WL_DBG(("type:%d length:%d not matching.\n",
+								type, nla_len(inner)));
+							err = -EINVAL;
+							goto exit;
+						}
+						dummy = (int8)nla_get_u8(inner);
+						break;
 					}
-					j++;
+				}
+				if (++j > PFN_SWC_MAX_NUM_APS) {
+					WL_DBG(("nbssid:%d exeed limit.\n",
+						hotlist_params->nbssid));
+					err = -EINVAL;
+					goto exit;
 				}
 				hotlist_params->nbssid = j;
-				break;
-			case GSCAN_ATTRIBUTE_HOTLIST_FLUSH:
-				flush = nla_get_u8(iter);
-				break;
-			case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE:
-				hotlist_params->lost_ap_window = nla_get_u32(iter);
-				break;
 			}
+			break;
+		case GSCAN_ATTRIBUTE_HOTLIST_FLUSH:
+			if (nla_len(iter) != sizeof(uint8)) {
+				WL_DBG(("type:%d length:%d not matching.\n",
+					type, nla_len(inner)));
+				err = -EINVAL;
+				goto exit;
+			}
+			flush = nla_get_u8(iter);
+			break;
+		case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE:
+			if (nla_len(iter) != sizeof(uint32)) {
+				WL_DBG(("type:%d length:%d not matching.\n",
+					type, nla_len(inner)));
+				err = -EINVAL;
+				goto exit;
+			}
+			hotlist_params->lost_ap_window = (uint16)nla_get_u32(iter);
+			break;
+		default:
+			WL_DBG(("Unknown type %d\n", type));
+			err = -EINVAL;
+			goto exit;
+		}
 
 	}
 
@@ -766,10 +888,13 @@
 	return err;
 }
 
+#ifdef DHD_ANQPO_SUPPORT
 static int wl_cfgvendor_gscan_anqpo_config(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
-	int err = BCME_ERROR, rem, type, hs_list_size = 0, malloc_size, i = 0, j, k, num_oi, oi_len;
+	int err = BCME_ERROR, rem, type, malloc_size, i = 0;
+	uint32 hs_list_size = 0;
+	int j, k, num_oi, oi_len;
 	wifi_passpoint_network *hs_list = NULL, *src_hs;
 	wl_anqpo_pfn_hs_list_t *anqpo_hs_list;
 	wl_anqpo_pfn_hs_t *dst_hs;
@@ -780,52 +905,100 @@
 	char *rcid;
 
 	nla_for_each_attr(iter, data, len, rem) {
-		type = nla_type(iter);
-		switch (type) {
-			case GSCAN_ATTRIBUTE_ANQPO_HS_LIST:
-				if (hs_list_size > 0) {
-					hs_list = kmalloc(hs_list_size*sizeof(wifi_passpoint_network), GFP_KERNEL);
-					if (hs_list == NULL) {
-						WL_ERR(("failed to allocate hs_list\n"));
-						return -ENOMEM;
-					}
-				}
-				nla_for_each_nested(outer, iter, tmp) {
-					nla_for_each_nested(inner, outer, tmp1) {
-						type = nla_type(inner);
-
-						switch (type) {
-							case GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID:
-								hs_list[i].id = nla_get_u32(inner);
-								WL_ERR(("%s: net id: %d\n", __func__, hs_list[i].id));
-								break;
-							case GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM:
-								memcpy(hs_list[i].realm,
-								  nla_data(inner), 256);
-								WL_ERR(("%s: realm: %s\n", __func__, hs_list[i].realm));
-								break;
-							case GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID:
-								memcpy(hs_list[i].roamingConsortiumIds,
-								  nla_data(inner), 128);
-								break;
-							case GSCAN_ATTRIBUTE_ANQPO_HS_PLMN:
-								memcpy(hs_list[i].plmn,
-								  nla_data(inner), 3);
-								WL_ERR(("%s: plmn: %c %c %c\n", __func__, hs_list[i].plmn[0], hs_list[i].plmn[1], hs_list[i].plmn[2]));
-								break;
-						}
-					}
-					i++;
-				}
-				break;
-			case GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE:
-				hs_list_size = nla_get_u32(iter);
-				WL_ERR(("%s: ANQPO: %d\n", __func__, hs_list_size));
-				break;
-			default:
-				WL_ERR(("Unknown type: %d\n", type));
-				return err;
+	type = nla_type(iter);
+	switch (type) {
+	case GSCAN_ATTRIBUTE_ANQPO_HS_LIST:
+		if (hs_list) {
+			err = -EINVAL;
+			goto exit;
 		}
+		if (hs_list_size > GSCAN_ANQPO_MAX_HS_LIST_SIZE) {
+			err = -EINVAL;
+			goto exit;
+		}
+		if (hs_list_size > 0) {
+			hs_list = kzalloc(hs_list_size *
+				sizeof(wifi_passpoint_network), GFP_KERNEL);
+			if (!hs_list) {
+				WL_ERR(("failed to allocate hs_list\n"));
+				return -ENOMEM;
+			}
+		}
+		nla_for_each_nested(outer, iter, tmp) {
+			if (i == hs_list_size)
+				break;
+			nla_for_each_nested(inner, outer, tmp1) {
+			type = nla_type(inner);
+
+			switch (type) {
+			case GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID:
+				if (nla_len(inner) != sizeof(hs_list[i].id)) {
+					err = -EINVAL;
+					goto exit;
+				}
+				hs_list[i].id = nla_get_u32(inner);
+				WL_DBG(("%s: net id: %d\n",
+					__func__, hs_list[i].id));
+				break;
+			case GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM:
+				if (nla_len(inner) !=
+					sizeof(hs_list[i].realm)) {
+					err = -EINVAL;
+					goto exit;
+				}
+				memcpy(hs_list[i].realm, nla_data(inner),
+				       sizeof(hs_list[i].realm));
+				WL_DBG(("%s: realm: %s\n",
+					__func__, hs_list[i].realm));
+				break;
+			case GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID:
+				if (nla_len(inner) != sizeof(hs_list[i].
+					roamingConsortiumIds)) {
+					err = -EINVAL;
+					goto exit;
+				}
+				memcpy(hs_list[i].roamingConsortiumIds,
+				       nla_data(inner),
+				       sizeof(hs_list[i].roamingConsortiumIds));
+				break;
+			case GSCAN_ATTRIBUTE_ANQPO_HS_PLMN:
+				if (nla_len(inner) != sizeof(hs_list[i].plmn)) {
+					err = -EINVAL;
+					goto exit;
+				}
+				memcpy(hs_list[i].plmn,
+				       nla_data(inner),
+				       sizeof(hs_list[i].plmn));
+				WL_DBG(("%s: plmn: %c %c %c\n",
+					__func__, hs_list[i].plmn[0],
+					hs_list[i].plmn[1],
+					hs_list[i].plmn[2]));
+				break;
+			}
+			}
+			i++;
+		}
+		break;
+	case GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE:
+		if (nla_len(iter) != sizeof(hs_list_size)) {
+			err = -EINVAL;
+			goto exit;
+		}
+		hs_list_size = nla_get_u32(iter);
+		if ((hs_list_size == 0) ||
+		    (hs_list_size > GSCAN_ANQPO_MAX_HS_LIST_SIZE)) {
+			WL_ERR(("%s: ANQPO: %d\n", __func__, hs_list_size));
+			err = -EINVAL;
+			goto exit;
+		}
+		WL_DBG(("%s: ANQPO: %d\n", __func__, hs_list_size));
+		break;
+	default:
+		WL_ERR(("Unknown type: %d\n", type));
+		err = -EINVAL;
+		goto exit;
+	}
+
 	}
 
 	malloc_size = OFFSETOF(wl_anqpo_pfn_hs_list_t, hs) +
@@ -873,7 +1046,7 @@
 	kfree(hs_list);
 	return err;
 }
-
+#endif /* DHD_ANQPO_SUPPORT */
 static int wl_cfgvendor_set_batch_scan_cfg(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
@@ -1413,13 +1586,18 @@
 	}
 
 	memset(&rtt_param, 0, sizeof(rtt_param));
+	if (len <= 0) {
+		err = BCME_ERROR;
+		goto exit;
+	}
 	nla_for_each_attr(iter, data, len, rem) {
 		type = nla_type(iter);
 		switch (type) {
 		case RTT_ATTRIBUTE_TARGET_CNT:
 			target_cnt = nla_get_u8(iter);
-			if (rtt_param.rtt_target_cnt > RTT_MAX_TARGET_CNT) {
-				WL_ERR(("exceed max target count : %d\n",
+			if ((target_cnt <= 0) ||
+			    (target_cnt > RTT_MAX_TARGET_CNT)) {
+				WL_ERR(("target_cnt is not valid: %d",
 					target_cnt));
 				err = BCME_RANGE;
 				goto exit;
@@ -1433,6 +1611,13 @@
 			}
 			break;
 		case RTT_ATTRIBUTE_TARGET_INFO:
+			/* Added this variable for safe check to avoid crash
+			 * incase the caller did not respect the order
+			 */
+			if (!rtt_param.target_info) {
+				err = BCME_NOMEM;
+				goto exit;
+			}
 			rtt_target = rtt_param.target_info;
 			nla_for_each_nested(iter1, iter, rem1) {
 				nla_for_each_nested(iter2, iter1, rem2) {
@@ -1553,6 +1738,7 @@
 exit:
 	/* free the target info list */
 	kfree(rtt_param.target_info);
+	rtt_param.target_info = NULL;
 	return err;
 }
 
@@ -1561,46 +1747,63 @@
 	const void *data, int len)
 {
 	int err = 0, rem, type, target_cnt = 0;
-	int target_cnt_chk = 0;
+	int target_idx = 0;
 	const struct nlattr *iter;
-	struct ether_addr *mac_list = NULL, *mac_addr = NULL;
+	struct ether_addr *mac_list = NULL;
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 
+	if (len <= 0) {
+		err = -EINVAL;
+		goto exit;
+	}
 	nla_for_each_attr(iter, data, len, rem) {
 		type = nla_type(iter);
 		switch (type) {
 		case RTT_ATTRIBUTE_TARGET_CNT:
 			if (mac_list != NULL) {
 				WL_ERR(("mac_list is not NULL\n"));
+				err = -EINVAL;
 				goto exit;
 			}
 			target_cnt = nla_get_u8(iter);
-			if (target_cnt > 0) {
+			if ((target_cnt > 0) &&
+			    (target_cnt < RTT_MAX_TARGET_CNT)) {
 				mac_list = (struct ether_addr *)kzalloc(target_cnt * ETHER_ADDR_LEN,
 					GFP_KERNEL);
 				if (mac_list == NULL) {
 					WL_ERR(("failed to allocate mem for mac list\n"));
+					err = -EINVAL;
 					goto exit;
 				}
-				mac_addr = &mac_list[0];
 			} else {
 				/* cancel the current whole RTT process */
 				goto cancel;
 			}
 			break;
 		case RTT_ATTRIBUTE_TARGET_MAC:
-			if (mac_addr) {
-				memcpy(mac_addr++, nla_data(iter), ETHER_ADDR_LEN);
-				target_cnt_chk++;
-				if (target_cnt_chk > target_cnt) {
-					WL_ERR(("over target count\n"));
-					goto exit;
-				}
-				break;
-			} else {
-				WL_ERR(("mac_list is NULL\n"));
+			if (!mac_list) {
+				err = -EINVAL;
 				goto exit;
 			}
+
+			if (target_idx >= target_cnt) {
+				err = -EINVAL;
+				goto exit;
+			}
+
+			if (nla_len(iter) != ETHER_ADDR_LEN) {
+				err = -EINVAL;
+				goto exit;
+			}
+
+			memcpy(&mac_list[target_idx], nla_data(iter),
+			       ETHER_ADDR_LEN);
+			target_idx++;
+			break;
+
+		default:
+			err = -EINVAL;
+			goto exit;
 		}
 	}
 cancel:
@@ -2468,6 +2671,7 @@
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_bssid_blacklist
 	},
+#ifdef DHD_ANQPO_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -2476,6 +2680,7 @@
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_gscan_anqpo_config
 	},
+#endif /* DHD_ANQPO_SUPPORT */
 #endif /* GSCAN_SUPPORT */
 	{
 		{
@@ -2582,7 +2787,9 @@
 		{ OUI_GOOGLE, GOOGLE_SCAN_EPNO_EVENT },
 		{ OUI_GOOGLE, GOOGLE_DEBUG_RING_EVENT },
 		{ OUI_GOOGLE, GOOGLE_FW_DUMP_EVENT },
+#ifdef DHD_ANQPO_SUPPORT
 		{ OUI_GOOGLE, GOOGLE_PNO_HOTSPOT_FOUND_EVENT },
+#endif /* DHD_ANQPO_SUPPORT */
 		{ OUI_GOOGLE, GOOGLE_RSSI_MONITOR_EVENT },
 		{ OUI_GOOGLE, GOOGLE_MKEEP_ALIVE_EVENT }
 };
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 3890c98..eb1508e 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -159,16 +159,16 @@
 	int g;
 	struct fdtable *fdt = NULL;
 	const struct cred *cred;
-	pid_t ppid, tpid;
+	pid_t ppid = 0, tpid = 0;
+	struct task_struct *leader = NULL;
 
 	rcu_read_lock();
-	ppid = pid_alive(p) ?
-		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
-	tpid = 0;
 	if (pid_alive(p)) {
 		struct task_struct *tracer = ptrace_parent(p);
 		if (tracer)
 			tpid = task_pid_nr_ns(tracer, ns);
+		ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
+		leader = p->group_leader;
 	}
 	cred = get_task_cred(p);
 	seq_printf(m,
@@ -210,12 +210,13 @@
 		seq_printf(m, "%d ",
 			   from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
 	put_cred(cred);
-
 #ifdef CONFIG_PID_NS
-	seq_puts(m, "\nNStgid:");
-	for (g = ns->level; g <= pid->level; g++)
-		seq_printf(m, "\t%d",
-			task_tgid_nr_ns(p, pid->numbers[g].ns));
+	if (leader) {
+		seq_puts(m, "\nNStgid:");
+		for (g = ns->level; g <= pid->level; g++)
+			seq_printf(m, "\t%d",
+				task_pid_nr_ns(leader, pid->numbers[g].ns));
+	}
 	seq_puts(m, "\nNSpid:");
 	for (g = ns->level; g <= pid->level; g++)
 		seq_printf(m, "\t%d",
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2cc2136..dccbd2c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1448,10 +1448,17 @@
 	 * If this was a group event with sibling events then
 	 * upgrade the siblings to singleton events by adding them
 	 * to whatever list we are on.
+	 * If this isn't on a list, make sure we still remove the sibling's
+	 * group_entry from this sibling_list; otherwise, when that sibling
+	 * is later deallocated, it will try to remove itself from this
+	 * sibling_list, which may well have been deallocated already,
+	 * resulting in a use-after-free.
 	 */
 	list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) {
 		if (list)
 			list_move_tail(&sibling->group_entry, list);
+		else
+			list_del_init(&sibling->group_entry);
 		sibling->group_leader = sibling;
 
 		/* Inherit group flags from the previous leader */
diff --git a/mm/memory.c b/mm/memory.c
index d5f2ae9..04979a2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2636,6 +2636,10 @@
 
 	pte_unmap(page_table);
 
+	/* File mapping without ->vm_ops ? */
+	if (vma->vm_flags & VM_SHARED)
+		return VM_FAULT_SIGBUS;
+
 	/* Check if we need to add a guard page to the stack */
 	if (check_stack_guard_page(vma, address) < 0)
 		return VM_FAULT_SIGBUS;
@@ -3040,6 +3044,9 @@
 			- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 
 	pte_unmap(page_table);
+	/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
+	if (!vma->vm_ops->fault)
+		return VM_FAULT_SIGBUS;
 	if (!(flags & FAULT_FLAG_WRITE))
 		return do_read_fault(mm, vma, address, pmd, pgoff, flags,
 				orig_pte);
@@ -3205,11 +3212,10 @@
 	entry = ACCESS_ONCE(*pte);
 	if (!pte_present(entry)) {
 		if (pte_none(entry)) {
-			if (vma->vm_ops) {
-				if (likely(vma->vm_ops->fault))
-					return do_linear_fault(mm, vma, address,
+			if (vma->vm_ops)
+				return do_linear_fault(mm, vma, address,
 						pte, pmd, flags, entry);
-			}
+
 			return do_anonymous_page(mm, vma, address,
 						 pte, pmd, flags);
 		}