Merge branch 'android-msm-bullhead-3.10-security-next' into android-msm-bullhead-3.10

March 2018.1
Change-Id: Ice243e35cad9f32e9ab30bc007f00440bae25aff
diff --git a/afcebb8.diff b/afcebb8.diff
new file mode 100644
index 0000000..deade5b
--- /dev/null
+++ b/afcebb8.diff
@@ -0,0 +1,38 @@
+From afcebb82f391776dc332a268d6a582f8de0b7a23 Mon Sep 17 00:00:00 2001
+From: Srinivas Girigowda <sgirigow@codeaurora.org>
+Date: Wed, 26 Jul 2017 12:17:20 +0530
+Subject: [PATCH] qcacld-2.0: Fix incorrect processing of encrypted auth frame
+
+qcacld-3.0 to qcacld-2.0 propagation.
+
+Fix incorrect processing of encrypted auth frame by allocating
+appropriate local buffer and using correct type for frame length.
+
+Change-Id: I0d17656230c4a032c6a190835343e5da737978eb
+CRs-Fixed: 2082544
+Bug: 67030205
+Signed-off-by: Srinivas Girigowda <sgirigow@codeaurora.org>
+---
+
+diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
+index 049c86a..909a300 100644
+--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
++++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
+@@ -734,7 +734,7 @@
+     {
+         tANI_U8 i   = ctx.i;
+         tANI_U8 j   = ctx.j;
+-        tANI_U8 len = (tANI_U8) frameLen;
++        tANI_U16 len = frameLen;
+ 
+         while (len-- > 0)
+         {
+@@ -816,7 +816,7 @@
+     // Compute CRC-32 and place them in last 4 bytes of encrypted body
+     limComputeCrc32(icv,
+                     (tANI_U8 *) pPlainBody,
+-                    (tANI_U8) (frameLen - SIR_MAC_WEP_ICV_LENGTH));
++                    (frameLen - SIR_MAC_WEP_ICV_LENGTH));
+ 
+     // Compare RX_ICV with computed ICV
+     for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++)
diff --git a/afcebb8.diff.zip b/afcebb8.diff.zip
new file mode 100644
index 0000000..16b7b66
--- /dev/null
+++ b/afcebb8.diff.zip
Binary files differ
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index 6916507..5160c7b 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -36,7 +36,7 @@
 static int diag_dbgfs_finished;
 static int diag_dbgfs_dci_data_index;
 static int diag_dbgfs_dci_finished;
-
+static struct mutex diag_dci_dbgfs_mutex;
 static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
 				      size_t count, loff_t *ppos)
 {
@@ -357,6 +357,7 @@
 	buf_size = ksize(buf);
 	bytes_remaining = buf_size;
 
+	mutex_lock(&diag_dci_dbgfs_mutex);
 	if (diag_dbgfs_dci_data_index == 0) {
 		bytes_written =
 			scnprintf(buf, buf_size,
@@ -412,8 +413,8 @@
 		}
 		temp_data++;
 	}
-
 	diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1;
+	mutex_unlock(&diag_dci_dbgfs_mutex);
 	bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf,
 								bytes_in_buf);
 	kfree(buf);
@@ -1084,6 +1085,7 @@
 		pr_warn("diag: could not allocate memory for dci debug info\n");
 
 	mutex_init(&dci_stat_mutex);
+	mutex_init(&diag_dci_dbgfs_mutex);
 	return 0;
 err:
 	kfree(dci_traffic);
@@ -1100,6 +1102,7 @@
 
 	kfree(dci_traffic);
 	mutex_destroy(&dci_stat_mutex);
+	mutex_destroy(&diag_dci_dbgfs_mutex);
 }
 #else
 int diag_debugfs_init(void) { return 0; }
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index c9461d6..be581c2 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1051,14 +1051,18 @@
 {
 	int i;
 
+	mutex_lock(&driver->diagchar_mutex);
 	for (i = 0; i < driver->num_clients; i++)
 		if (driver->client_map[i].pid == current->tgid)
 			break;
 
-	if (i == driver->num_clients)
+	if (i == driver->num_clients) {
+		mutex_unlock(&driver->diagchar_mutex);
 		return -EINVAL;
+	}
 
 	driver->data_ready[i] |= DEINIT_TYPE;
+	mutex_unlock(&driver->diagchar_mutex);
 	wake_up_interruptible(&driver->wait_q);
 
 	return 1;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ada164e..60d77af 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1016,6 +1016,8 @@
 	unsigned int rsize = 0;
 	char *rdesc;
 	int ret, n;
+	int num_descriptors;
+	size_t offset = offsetof(struct hid_descriptor, desc);
 
 	quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
 			le16_to_cpu(dev->descriptor.idProduct));
@@ -1038,10 +1040,18 @@
 		return -ENODEV;
 	}
 
+	if (hdesc->bLength < sizeof(struct hid_descriptor)) {
+		dbg_hid("hid descriptor is too short\n");
+		return -EINVAL;
+	}
+
 	hid->version = le16_to_cpu(hdesc->bcdHID);
 	hid->country = hdesc->bCountryCode;
 
-	for (n = 0; n < hdesc->bNumDescriptors; n++)
+	num_descriptors = min_t(int, hdesc->bNumDescriptors,
+	       (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
+
+	for (n = 0; n < num_descriptors; n++)
 		if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
 			rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
 
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
index 0390e0e..40d731b 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
@@ -1114,6 +1114,9 @@
 			break;
 		}
 		break;
+	case VIDIOC_MSM_FLASH_CFG:
+		pr_err("invalid cmd 0x%x received\n", cmd);
+		return -EINVAL;
 	default:
 		return msm_flash_subdev_ioctl(sd, cmd, arg);
 	}
diff --git a/drivers/platform/msm/ipa/ipa_flt.c b/drivers/platform/msm/ipa/ipa_flt.c
index 72342c2..54328b7 100644
--- a/drivers/platform/msm/ipa/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_flt.c
@@ -1017,7 +1017,7 @@
 				goto error;
 			}
 
-			if (rt_tbl->cookie != IPA_COOKIE) {
+			if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
 				IPAERR("RT table cookie is invalid\n");
 				goto error;
 			}
@@ -1038,7 +1038,7 @@
 	}
 	INIT_LIST_HEAD(&entry->link);
 	entry->rule = *rule;
-	entry->cookie = IPA_COOKIE;
+	entry->cookie = IPA_FLT_COOKIE;
 	entry->rt_tbl = rt_tbl;
 	entry->tbl = tbl;
 	if (add_rear) {
@@ -1057,13 +1057,19 @@
 	if (id < 0) {
 		IPAERR("failed to add to tree\n");
 		WARN_ON(1);
+		goto ipa_insert_failed;
 	}
 	*rule_hdl = id;
 	entry->id = id;
 	IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
 
 	return 0;
-
+ipa_insert_failed:
+	tbl->rule_cnt--;
+	if (entry->rt_tbl)
+		entry->rt_tbl->ref_cnt--;
+	list_del(&entry->link);
+	kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
 error:
 	return -EPERM;
 }
@@ -1079,7 +1085,7 @@
 		return -EINVAL;
 	}
 
-	if (entry->cookie != IPA_COOKIE) {
+	if (entry->cookie != IPA_FLT_COOKIE) {
 		IPAERR("bad params\n");
 		return -EINVAL;
 	}
@@ -1111,7 +1117,7 @@
 		goto error;
 	}
 
-	if (entry->cookie != IPA_COOKIE) {
+	if (entry->cookie != IPA_FLT_COOKIE) {
 		IPAERR("bad params\n");
 		goto error;
 	}
@@ -1132,7 +1138,7 @@
 				goto error;
 			}
 
-			if (rt_tbl->cookie != IPA_COOKIE) {
+			if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
 				IPAERR("RT table cookie is invalid\n");
 				goto error;
 			}
diff --git a/drivers/platform/msm/ipa/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_hdr.c
index 52be0fb..92974c7 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -469,7 +469,7 @@
 {
 	struct ipa_hdr_entry *hdr_entry;
 	struct ipa_hdr_proc_ctx_entry *entry;
-	struct ipa_hdr_proc_ctx_offset_entry *offset;
+	struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
 	u32 bin;
 	struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
 	int id;
@@ -484,7 +484,7 @@
 	}
 
 	hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
-	if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
+	if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
 		IPAERR("hdr_hdl is invalid\n");
 		return -EINVAL;
 	}
@@ -501,7 +501,7 @@
 	entry->hdr = hdr_entry;
 	if (add_ref_hdr)
 		hdr_entry->ref_cnt++;
-	entry->cookie = IPA_COOKIE;
+	entry->cookie = IPA_PROC_HDR_COOKIE;
 
 	needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
 			sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -553,6 +553,7 @@
 	if (id < 0) {
 		IPAERR("failed to alloc id\n");
 		WARN_ON(1);
+		goto ipa_insert_failed;
 	}
 	entry->id = id;
 	proc_ctx->proc_ctx_hdl = id;
@@ -560,6 +561,13 @@
 
 	return 0;
 
+ipa_insert_failed:
+	if (offset)
+		list_move(&offset->link,
+		&htbl->head_free_offset_list[offset->bin]);
+	entry->offset_entry = NULL;
+	list_del(&entry->link);
+	htbl->proc_ctx_cnt--;
 bad_len:
 	if (add_ref_hdr)
 		hdr_entry->ref_cnt--;
@@ -572,7 +580,7 @@
 static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
 {
 	struct ipa_hdr_entry *entry;
-	struct ipa_hdr_offset_entry *offset;
+	struct ipa_hdr_offset_entry *offset = NULL;
 	u32 bin;
 	struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
 	int id;
@@ -603,7 +611,7 @@
 	entry->type = hdr->type;
 	entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
 	entry->eth2_ofst = hdr->eth2_ofst;
-	entry->cookie = IPA_COOKIE;
+	entry->cookie = IPA_HDR_COOKIE;
 
 	if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
 		bin = IPA_HDR_BIN0;
@@ -685,6 +693,7 @@
 	if (id < 0) {
 		IPAERR("failed to alloc id\n");
 		WARN_ON(1);
+		 goto ipa_insert_failed;
 	}
 	entry->id = id;
 	hdr->hdr_hdl = id;
@@ -709,10 +718,19 @@
 	entry->ref_cnt--;
 	hdr->hdr_hdl = 0;
 	ipa_id_remove(id);
+ipa_insert_failed:
+	 if (entry->is_hdr_proc_ctx) {
+		dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
+			entry->hdr_len, DMA_TO_DEVICE);
+	} else {
+		if (offset)
+			list_move(&offset->link,
+			&htbl->head_free_offset_list[offset->bin]);
+		entry->offset_entry = NULL;
+	}
+
 	htbl->hdr_cnt--;
 	list_del(&entry->link);
-	dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
-			entry->hdr_len, DMA_TO_DEVICE);
 bad_hdr_len:
 	entry->cookie = 0;
 	kmem_cache_free(ipa_ctx->hdr_cache, entry);
@@ -727,7 +745,7 @@
 	struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
 
 	entry = ipa_id_find(proc_ctx_hdl);
-	if (!entry || (entry->cookie != IPA_COOKIE)) {
+	if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
 		IPAERR("bad parm\n");
 		return -EINVAL;
 	}
@@ -778,7 +796,7 @@
 		return -EINVAL;
 	}
 
-	if (!entry || (entry->cookie != IPA_COOKIE)) {
+	if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
 		IPAERR("bad parm\n");
 		return -EINVAL;
 	}
@@ -1314,7 +1332,7 @@
 		goto bail;
 	}
 
-	if (entry == NULL || entry->cookie != IPA_COOKIE) {
+	if (entry == NULL || entry->cookie != IPA_HDR_COOKIE) {
 		IPAERR("bad params\n");
 		result = -EINVAL;
 		goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 3f40633..432be55 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.h
@@ -31,6 +31,12 @@
 #define DRV_NAME "ipa"
 #define NAT_DEV_NAME "ipaNatTable"
 #define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
 #define MTU_BYTE 1500
 
 #define IPA_NUM_PIPES 0x14
@@ -167,8 +173,8 @@
  */
 struct ipa_flt_entry {
 	struct list_head link;
-	struct ipa_flt_rule rule;
 	u32 cookie;
+	struct ipa_flt_rule rule;
 	struct ipa_flt_tbl *tbl;
 	struct ipa_rt_tbl *rt_tbl;
 	u32 hw_len;
@@ -193,13 +199,13 @@
  */
 struct ipa_rt_tbl {
 	struct list_head link;
+	u32 cookie;
 	struct list_head head_rt_rule_list;
 	char name[IPA_RESOURCE_NAME_MAX];
 	u32 idx;
 	u32 rule_cnt;
 	u32 ref_cnt;
 	struct ipa_rt_tbl_set *set;
-	u32 cookie;
 	bool in_sys;
 	u32 sz;
 	struct ipa_mem_buffer curr_mem;
@@ -230,6 +236,7 @@
  */
 struct ipa_hdr_entry {
 	struct list_head link;
+	u32 cookie;
 	u8 hdr[IPA_HDR_MAX_SIZE];
 	u32 hdr_len;
 	char name[IPA_RESOURCE_NAME_MAX];
@@ -239,7 +246,6 @@
 	dma_addr_t phys_base;
 	struct ipa_hdr_proc_ctx_entry *proc_ctx;
 	struct ipa_hdr_offset_entry *offset_entry;
-	u32 cookie;
 	u32 ref_cnt;
 	int id;
 	u8 is_eth2_ofst_valid;
@@ -324,10 +330,10 @@
  */
 struct ipa_hdr_proc_ctx_entry {
 	struct list_head link;
+	u32 cookie;
 	enum ipa_hdr_proc_type type;
 	struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
 	struct ipa_hdr_entry *hdr;
-	u32 cookie;
 	u32 ref_cnt;
 	int id;
 	bool user_deleted;
@@ -383,8 +389,8 @@
  */
 struct ipa_rt_entry {
 	struct list_head link;
-	struct ipa_rt_rule rule;
 	u32 cookie;
+	struct ipa_rt_rule rule;
 	struct ipa_rt_tbl *tbl;
 	struct ipa_hdr_entry *hdr;
 	struct ipa_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_rt.c b/drivers/platform/msm/ipa/ipa_rt.c
index 81c6331..ba28ba7 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.c
@@ -839,7 +839,7 @@
 		INIT_LIST_HEAD(&entry->link);
 		strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
 		entry->set = set;
-		entry->cookie = IPA_COOKIE;
+		entry->cookie = IPA_RT_TBL_COOKIE;
 		entry->in_sys = (ip == IPA_IP_v4) ?
 			!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
 		set->tbl_cnt++;
@@ -852,12 +852,16 @@
 		if (id < 0) {
 			IPAERR("failed to add to tree\n");
 			WARN_ON(1);
+			goto ipa_insert_failed;
 		}
 		entry->id = id;
 	}
 
 	return entry;
 
+ipa_insert_failed:
+	set->tbl_cnt--;
+	list_del(&entry->link);
 fail_rt_idx_alloc:
 	entry->cookie = 0;
 	kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -870,7 +874,7 @@
 	enum ipa_ip_type ip = IPA_IP_MAX;
 	u32 id;
 
-	if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+	if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
 		IPAERR("bad parms\n");
 		return -EINVAL;
 	}
@@ -884,8 +888,10 @@
 		ip = IPA_IP_v4;
 	else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
 		ip = IPA_IP_v6;
-	else
+	else {
 		WARN_ON(1);
+		return -EPERM;
+	}
 
 	if (!entry->in_sys) {
 		list_del(&entry->link);
@@ -924,13 +930,14 @@
 
 	if (rule->hdr_hdl) {
 		hdr = ipa_id_find(rule->hdr_hdl);
-		if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+		if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
 			IPAERR("rt rule does not point to valid hdr\n");
 			goto error;
 		}
 	} else if (rule->hdr_proc_ctx_hdl) {
 		proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
-		if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+		if ((proc_ctx == NULL) ||
+			(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
 			IPAERR("rt rule does not point to valid proc ctx\n");
 			goto error;
 		}
@@ -938,7 +945,7 @@
 
 
 	tbl = __ipa_add_rt_tbl(ip, name);
-	if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+	if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
 		IPAERR("bad params\n");
 		goto error;
 	}
@@ -959,7 +966,7 @@
 		goto error;
 	}
 	INIT_LIST_HEAD(&entry->link);
-	entry->cookie = IPA_COOKIE;
+	entry->cookie = IPA_RT_RULE_COOKIE;
 	entry->rule = *rule;
 	entry->tbl = tbl;
 	entry->hdr = hdr;
@@ -1049,7 +1056,7 @@
 		return -EINVAL;
 	}
 
-	if (entry->cookie != IPA_COOKIE) {
+	if (entry->cookie != IPA_RT_RULE_COOKIE) {
 		IPAERR("bad params\n");
 		return -EINVAL;
 	}
@@ -1288,7 +1295,7 @@
 	}
 	mutex_lock(&ipa_ctx->lock);
 	entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
-	if (entry && entry->cookie == IPA_COOKIE) {
+	if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
 		if (entry->ref_cnt == ((u32)~0U)) {
 			IPAERR("fail: ref count crossed limit\n");
 			goto ret;
@@ -1332,7 +1339,7 @@
 		goto ret;
 	}
 
-	if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+	if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
 		IPAERR("bad parms\n");
 		result = -EINVAL;
 		goto ret;
@@ -1342,8 +1349,11 @@
 		ip = IPA_IP_v4;
 	else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
 		ip = IPA_IP_v6;
-	else
+	else {
 		WARN_ON(1);
+		result = -EINVAL;
+		goto ret;
+	}
 
 	entry->ref_cnt--;
 	if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1371,7 +1381,7 @@
 
 	if (rtrule->rule.hdr_hdl) {
 		hdr = ipa_id_find(rtrule->rule.hdr_hdl);
-		if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+		if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
 			IPAERR("rt rule does not point to valid hdr\n");
 			goto error;
 		}
@@ -1383,7 +1393,7 @@
 		goto error;
 	}
 
-	if (entry->cookie != IPA_COOKIE) {
+	if (entry->cookie != IPA_RT_RULE_COOKIE) {
 		IPAERR("bad params\n");
 		goto error;
 	}
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index 93248b9..3cbda0b 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015,2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -349,11 +349,16 @@
 	int ret;
 	struct cpu_activity_info *node;
 	struct cpu_static_info *sp, *clear_sp;
-	int mpidr = (argp->cluster << 8);
-	int cpumask = argp->cpumask;
+	int cpumask, cluster, mpidr;
 	int cpu = num_possible_cpus();
 
-	pr_debug("cpumask %d, cluster: %d\n", argp->cpumask, argp->cluster);
+	get_user(cpumask, &argp->cpumask);
+	get_user(cluster, &argp->cluster);
+	mpidr = cluster << 8;
+
+	pr_debug("%s: cpumask %d, cluster: %d\n", __func__, cpumask,
+					cluster);
+
 	for (i = 0; i < MAX_CORES_PER_CLUSTER; i++, cpumask >>= 1) {
 		if (!(cpumask & 0x01))
 			continue;
@@ -376,9 +381,10 @@
 	if (!sp)
 		return -ENOMEM;
 
-
+	mutex_lock(&policy_update_mutex);
 	sp->power = allocate_2d_array_uint32_t(node->sp->num_of_freqs);
 	if (IS_ERR_OR_NULL(sp->power)) {
+		mutex_unlock(&policy_update_mutex);
 		ret = PTR_ERR(sp->power);
 		kfree(sp);
 		return ret;
@@ -397,12 +403,12 @@
 	/* Copy the same power values for all the cpus in the cpumask
 	 * argp->cpumask within the cluster (argp->cluster)
 	 */
+	get_user(cpumask, &argp->cpumask);
 	spin_lock(&update_lock);
-	cpumask = argp->cpumask;
 	for (i = 0; i < MAX_CORES_PER_CLUSTER; i++, cpumask >>= 1) {
 		if (!(cpumask & 0x01))
 			continue;
-		mpidr = (argp->cluster << CLUSTER_OFFSET_FOR_MPIDR);
+		mpidr = (cluster << CLUSTER_OFFSET_FOR_MPIDR);
 		mpidr |= i;
 		for_each_possible_cpu(cpu) {
 			if (!(cpu_logical_map(cpu) == mpidr))
@@ -421,11 +427,13 @@
 		}
 	}
 	spin_unlock(&update_lock);
+	mutex_unlock(&policy_update_mutex);
 
 	activate_power_table = true;
 	return 0;
 
 failed:
+	mutex_unlock(&policy_update_mutex);
 	for (i = 0; i < TEMP_DATA_POINTS; i++)
 		kfree(sp->power[i]);
 	kfree(sp->power);
diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 3ade903..5bac25bb 100644
--- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -552,6 +552,16 @@
 					 rx_pkt->pkt_meta.mpdu_hdr_len;
 
     /*
+	 * If the mpdu_data_len is greater than Max (2k), drop the frame
+	 */
+	if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
+		TLSHIM_LOGE("Data Len %d greater than max, dropping frame",
+			 rx_pkt->pkt_meta.mpdu_data_len);
+		vos_mem_free(rx_pkt);
+		return 0;
+	}
+
+    /*
      * saved_beacon means this beacon is a duplicate of one
      * sent earlier. roamCandidateInd flag is used to indicate to
      * PE that roam scan finished and a better candidate AP
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
index b0c844e..2a982b9 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
@@ -893,6 +893,7 @@
 static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
 {
 	tAniMsgHdr *msg_hdr;
+	int msg_len;
 	int ret;
 	struct nlattr *tb[CLD80211_ATTR_MAX + 1];
 
@@ -902,6 +903,10 @@
 		return;
 	}
 
+	/*
+	 * audit note: it is ok to pass a NULL policy here since only
+	 * one attribute is parsed and it is explicitly validated
+	 */
 	if (nla_parse(tb, CLD80211_ATTR_MAX, data, data_len, NULL)) {
 		hddLog(LOGE, FL("Invalid ATTR"));
 		return;
@@ -912,14 +917,22 @@
 		return;
 	}
 
-	msg_hdr = (tAniMsgHdr *)nla_data(tb[CLD80211_ATTR_DATA]);
-	if (!msg_hdr) {
-		hddLog(LOGE, FL("msg_hdr null"));
+	msg_len = nla_len(tb[CLD80211_ATTR_DATA]);
+	if (msg_len < sizeof(*msg_hdr)) {
+		hddLog(LOGE, FL("runt ATTR_DATA size %d"), msg_len);
 		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_NULL_MESSAGE_HEADER);
 		return;
 	}
-        oem_msg_callback(msg_hdr, nla_len(tb[CLD80211_ATTR_DATA]), pid);
 
+	msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]);
+	if (msg_len < (sizeof(*msg_hdr) + msg_hdr->length)) {
+		hddLog(LOGE, FL("Invalid nl msg len %d, msg hdr len %d"),
+			msg_len, msg_hdr->length);
+		send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+		return;
+	}
+
+    oem_msg_callback(msg_hdr, nla_len(tb[CLD80211_ATTR_DATA]), pid);
 	return;
 }
 
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
index 215f9c6..ab96e29 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
@@ -585,6 +585,7 @@
 #define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS      4
 #define SIR_MAC_KEY_LENGTH                   13   // WEP Maximum key length size
 #define SIR_MAC_AUTH_CHALLENGE_LENGTH        253
+#define SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH    128
 #define SIR_MAC_WEP_IV_LENGTH                4
 #define SIR_MAC_WEP_ICV_LENGTH               4
 #define SIR_MAC_CHALLENGE_ID_LEN             2
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
index 10f1872..0b100ae 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
@@ -36,7 +36,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Tue Jul  4 11:07:27 2017 from the following file(s):
+  * Wed Jul 12 16:02:49 2017 from the following file(s):
   *
   * dot11f.frms
   *
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index d03ae85..293bbca 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -2422,6 +2422,12 @@
               pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
               frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
 
+              if (frameLen < sizeof(pPubAction)) {
+                limLog(pMac, LOG1,
+                  FL("Received action frame of invalid len %d"), frameLen);
+                break;
+              }
+
               //Check if it is a P2P public action frame.
               if (vos_mem_compare(pPubAction->Oui, P2POui, 4))
               {
@@ -2599,6 +2605,12 @@
                 pHdr = WDA_GET_RX_MAC_HEADER(pBd);
                 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
 
+                if (frameLen < sizeof(pActionHdr)) {
+                  limLog(pMac, LOG1,
+                    FL("Received action frame of invalid len %d"), frameLen);
+                  break;
+                }
+
                 //Check if it is a P2P public action frame.
                 if (vos_mem_compare(pActionHdr->Oui, P2POui, 4))
                 {
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 17cb712..c5c72aa 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -297,7 +297,8 @@
             goto free;
         }
 
-        if (frameLen < LIM_ENCR_AUTH_BODY_LEN)
+        if ((frameLen < LIM_ENCR_AUTH_BODY_LEN_SAP) ||
+            (frameLen > LIM_ENCR_AUTH_BODY_LEN_SAP))
         {
             // Log error
             limLog(pMac, LOGE,
@@ -973,9 +974,9 @@
                             pAuthNode->fTimerStarted = 1;
 
                             /*
-                             * get random bytes and use as challenge text.
+                             * get random bytes and use as challenge text
                              */
-                            if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH ) ) )
+                            if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH ) ) )
                             {
                                limLog(pMac, LOGE,FL("Challenge text preparation failed in limProcessAuthFrame"));
                                goto free;
@@ -997,11 +998,12 @@
                             pRxAuthFrameBody->authTransactionSeqNumber + 1;
                             authFrame->authStatusCode =
                             eSIR_MAC_SUCCESS_STATUS;
+
                             authFrame->type   = SIR_MAC_CHALLENGE_TEXT_EID;
-                            authFrame->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+                            authFrame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
                             vos_mem_copy(authFrame->challengeText,
                                          pAuthNode->challengeText,
-                                         SIR_MAC_AUTH_CHALLENGE_LENGTH);
+                                         SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
 
                             limSendAuthMgmtFrame(
                                                 pMac, authFrame,
@@ -1603,7 +1605,7 @@
 
                 if (vos_mem_compare(pRxAuthFrameBody->challengeText,
                                     pAuthNode->challengeText,
-                                    SIR_MAC_AUTH_CHALLENGE_LENGTH))
+                                    SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH))
                 {
                     /// Challenge match. STA is autheticated !
 
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index bb43c12..41c7709 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -6590,8 +6590,17 @@
         vos_mem_copy(vendor_ie, pModifyIE->pIEBuffer,
                      pModifyIE->ieBufferlength);
     } else {
-        uint16_t new_length = pModifyIE->ieBufferlength + *pDstDataLen;
-        uint8_t *new_ptr = vos_mem_malloc(new_length);
+	uint8_t *new_ptr;
+	uint16_t new_length;
+
+	if (USHRT_MAX - pModifyIE->ieBufferlength < *pDstDataLen) {
+			limLog(pMac,LOGE,FL("U16 overflow due to %d + %d"),
+				pModifyIE->ieBufferlength, *pDstDataLen);
+			return false;
+		}
+
+        new_length = pModifyIE->ieBufferlength + *pDstDataLen;
+        new_ptr = vos_mem_malloc(new_length);
 
         if (NULL == new_ptr) {
             limLog(pMac, LOGE, FL("Memory allocation failed."));
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
index 4fb961c..3dd987b 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
@@ -48,6 +48,11 @@
                                  SIR_MAC_WEP_ICV_LENGTH + \
                                  SIR_MAC_CHALLENGE_ID_LEN)
 
+#define LIM_ENCR_AUTH_BODY_LEN_SAP  (SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + \
+                                     SIR_MAC_CHALLENGE_ID_LEN + \
+                                     SIR_MAC_AUTH_FRAME_INFO_LEN + \
+                                     SIR_MAC_WEP_IV_LENGTH + \
+                                     SIR_MAC_WEP_ICV_LENGTH)
 struct tLimPreAuthNode;
 
 tANI_U8        limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession);
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index aaa8803..2d9b319 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -3435,10 +3435,11 @@
                      * transaction number, status code and 128 bytes
                      * for challenge text.
                      */
-
+                    bodyLen = SIR_MAC_AUTH_FRAME_INFO_LEN +
+                              SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
+                              SIR_MAC_CHALLENGE_ID_LEN;
                     frameLen = sizeof(tSirMacMgmtHdr) +
-                               sizeof(tSirMacAuthFrame);
-                    bodyLen  = sizeof(tSirMacAuthFrameBody);
+                               bodyLen;
                 }
 
                 break;
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
index eaa9a37..afd6d82 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
@@ -4611,7 +4611,8 @@
 	wmi_rate_stats *rate_stats;
 	tSirLLStatsResults *link_stats_results;
 	u_int8_t *results, *t_peer_stats, *t_rate_stats;
-	u_int32_t count, num_rates=0, rate_cnt;
+	u_int32_t count, rate_cnt;
+	uint32_t total_num_rates = 0;
 	u_int32_t next_res_offset, next_peer_offset, next_rate_offset;
 	size_t peer_info_size, peer_stats_size, rate_stats_size;
 	size_t link_stats_results_size;
@@ -4641,8 +4642,8 @@
 	 * cmd_param_info contains
 	 * wmi_peer_stats_event_fixed_param fixed_param;
 	 * num_peers * size of(struct wmi_peer_link_stats)
-	 * num_rates * size of(struct wmi_rate_stats)
-	 * num_rates is the sum of the rates of all the peers.
+	 * total_num_rates * size of(struct wmi_rate_stats)
+	 * total_num_rates is the sum of the rates of all the peers.
 	 */
 	fixed_param = param_tlvs->fixed_param;
 	peer_stats  = param_tlvs->peer_stats;
@@ -4655,22 +4656,33 @@
 	}
 
 	do {
-		if (peer_stats->num_rates >
-			WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_rate_stats)) {
-			excess_data = true;
-			break;
-		} else {
-			buf_len = peer_stats->num_rates *
-					sizeof(wmi_rate_stats);
-		}
 		if (fixed_param->num_peers >
 			WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats)) {
 			excess_data = true;
 			break;
 		} else {
-			buf_len += fixed_param->num_peers *
+			buf_len = fixed_param->num_peers *
 				sizeof(wmi_peer_link_stats);
 		}
+		temp_peer_stats = (wmi_peer_link_stats *) peer_stats;
+		for (count = 0; count < fixed_param->num_peers; count++) {
+			if (temp_peer_stats->num_rates >
+			    WMA_SVC_MSG_MAX_SIZE / sizeof(wmi_rate_stats)) {
+				excess_data = true;
+				break;
+			} else {
+				total_num_rates += temp_peer_stats->num_rates;
+				if (total_num_rates >
+				    WMA_SVC_MSG_MAX_SIZE /
+				    sizeof(wmi_rate_stats)) {
+					excess_data = true;
+					break;
+				}
+				buf_len += temp_peer_stats->num_rates *
+					sizeof(wmi_rate_stats);
+			}
+			temp_peer_stats++;
+		}
 	} while (0);
 
 	if (excess_data ||
@@ -4681,21 +4693,12 @@
 		return -EINVAL;
 	}
 
-	/*
-	 * num_rates - sum of the rates of all the peers
-	 */
-	temp_peer_stats = (wmi_peer_link_stats*)peer_stats;
-	for (count = 0; count < fixed_param->num_peers; count++) {
-		num_rates += temp_peer_stats->num_rates;
-		temp_peer_stats++;
-	}
-
 	peer_stats_size = sizeof(tSirWifiPeerStat);
 	peer_info_size  = sizeof(tSirWifiPeerInfo);
 	rate_stats_size = sizeof(tSirWifiRateStat);
 	link_stats_results_size = sizeof(*link_stats_results) + peer_stats_size +
 			(fixed_param->num_peers * peer_info_size) +
-			(num_rates * rate_stats_size);
+			(total_num_rates * rate_stats_size);
 
 	link_stats_results = vos_mem_malloc(link_stats_results_size);
 	if (NULL == link_stats_results ) {
@@ -5310,6 +5313,12 @@
 		WMA_LOGE("%s: Invalid beacon buffer", __func__);
 		return;
 	}
+	if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
+			WMI_P2P_MAX_NOA_DESCRIPTORS) {
+		WMA_LOGE("%s: Too many descriptors %d", __func__,
+			 WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
+		return;
+	}
 
 	wmi_buf = wmi_buf_alloc(wma->wmi_handle, sizeof(*cmd));
 	if (!wmi_buf) {
@@ -5965,6 +5974,12 @@
 		descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
 		noa_ie.num_descriptors = (u_int8_t)descriptors;
 
+		if (noa_ie.num_descriptors > WMA_MAX_NOA_DESCRIPTORS) {
+			WMA_LOGD("Sizing down the no of desc %d to max",
+					noa_ie.num_descriptors);
+			noa_ie.num_descriptors = WMA_MAX_NOA_DESCRIPTORS;
+		}
+
 		WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, "
 				"num_descriptors = %u", __func__, noa_ie.index,
 				noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
@@ -31503,6 +31518,11 @@
 	nlo_event = param_buf->fixed_param;
 	WMA_LOGD("PNO match event received for vdev %d",
 		 nlo_event->vdev_id);
+	if (nlo_event->vdev_id >= wma->max_bssid) {
+		WMA_LOGE("Invalid vdev id in the NLO event %d",
+				nlo_event->vdev_id);
+		return -EINVAL;
+	}
 
 	node = &wma->interfaces[nlo_event->vdev_id];
 	if (node)
@@ -31651,7 +31671,8 @@
 	/* FW mapped vdev from ID
 	 * vdev_map = (1 << vdev_id)
 	 * So, host should unmap to ID */
-	for (vdev_id = 0; vdev_map != 0; vdev_id++)
+	for (vdev_id = 0; vdev_map != 0 && vdev_id < wma->max_bssid;
+	     vdev_id++)
 	{
 		if (!(vdev_map & 0x1))
 		{
@@ -34742,6 +34763,14 @@
 				 currentSeq);
 	}
 
+	if ((datalen > MAX_UTF_EVENT_LENGTH) ||
+		(wma_handle->utf_event_info.offset >
+		(MAX_UTF_EVENT_LENGTH - datalen))) {
+		WMA_LOGE("Excess data from firmware, offset:%zu, len:%d",
+			wma_handle->utf_event_info.offset, datalen);
+		return -EINVAL;
+	}
+
 	memcpy(&wma_handle->utf_event_info.data[wma_handle->utf_event_info.offset],
 	       &data[sizeof(segHdrInfo)],
                datalen);
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
index f5f3a72..80b9564 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
@@ -101,6 +101,8 @@
 
 #define FRAGMENT_SIZE 3072
 
+#define WMA_MAX_MGMT_MPDU_LEN     2000
+
 #define WMA_INVALID_VDEV_ID				0xFF
 #define MAX_MEM_CHUNKS					32
 #define WMA_MAX_VDEV_SIZE				20
diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
index a4e85e6..75fca9e 100644
--- a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
+++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
@@ -1633,7 +1633,7 @@
     eHalStatus status;
     tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;
     tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
-    tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST] = {0};
+    tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
     tANI_U8 count, valid_count = 0;
     vos_msg_t msg;
 
diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
index c19e9c0..7a94d1f 100644
--- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -35,7 +35,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Tue Jul  4 11:07:27 2017 from the following file(s):
+  * Wed Jul 12 16:02:49 2017 from the following file(s):
   *
   * dot11f.frms
   *
@@ -476,7 +476,7 @@
 {
     const tIEDefn *pIe, *pIeFirst;
     tANI_U8 *pBufRemaining = pBuf;
-    tANI_U8 len = 0;
+    tANI_U32 len = 0;
 
     (void)pCtx;
 
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 6524383..98a8750 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -511,15 +511,23 @@
 
 		} else if (header->bDescriptorType ==
 				USB_DT_INTERFACE_ASSOCIATION) {
+			struct usb_interface_assoc_descriptor *d;
+
+			d = (struct usb_interface_assoc_descriptor *)header;
+			if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
+				dev_warn(ddev,
+					 "config %d has an invalid interface association descriptor of length %d, skipping\n",
+					 cfgno, d->bLength);
+				continue;
+			}
+
 			if (iad_num == USB_MAXIADS) {
 				dev_warn(ddev, "found more Interface "
 					       "Association Descriptors "
 					       "than allocated for in "
 					       "configuration %d\n", cfgno);
 			} else {
-				config->intf_assoc[iad_num] =
-					(struct usb_interface_assoc_descriptor
-					*)header;
+				config->intf_assoc[iad_num] = d;
 				iad_num++;
 			}
 
@@ -820,10 +828,12 @@
 	for (i = 0; i < num; i++) {
 		buffer += length;
 		cap = (struct usb_dev_cap_header *)buffer;
-		length = cap->bLength;
 
-		if (total_len < length)
+		if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+			dev->bos->desc->bNumDeviceCaps = i;
 			break;
+		}
+		length = cap->bLength;
 		total_len -= length;
 
 		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 5f3bcd3..f3bbe21 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -188,6 +188,7 @@
 	kfree(tty);
  reset_open_count:
 	port->port.count = 0;
+	info->port = NULL;
 	usb_autopm_put_interface(serial->interface);
  error_get_interface:
 	usb_serial_put(serial);
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index fca1db3..9f0fd880 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -720,6 +720,7 @@
 	__u8  iFunction;
 } __attribute__ ((packed));
 
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE	8
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index cc05702..60f5c7b 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1320,10 +1320,6 @@
 
 	mutex_lock(&fanout_mutex);
 
-	err = -EINVAL;
-	if (!po->running)
-		goto out;
-
 	err = -EALREADY;
 	if (po->fanout)
 		goto out;
@@ -1361,7 +1357,10 @@
 		list_add(&match->list, &fanout_list);
 	}
 	err = -EINVAL;
-	if (match->type == type &&
+
+	spin_lock(&po->bind_lock);
+	if (po->running &&
+	    match->type == type &&
 	    match->prot_hook.type == po->prot_hook.type &&
 	    match->prot_hook.dev == po->prot_hook.dev) {
 		err = -ENOSPC;
@@ -1373,6 +1372,13 @@
 			err = 0;
 		}
 	}
+	spin_unlock(&po->bind_lock);
+
+	if (err && !atomic_read(&match->sk_ref)) {
+		list_del(&match->list);
+		kfree(match);
+	}
+
 out:
 	mutex_unlock(&fanout_mutex);
 	return err;
@@ -2508,17 +2514,20 @@
 static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
 {
 	struct packet_sock *po = pkt_sk(sk);
+	int ret = 0;
+
+	lock_sock(sk);
+
+	spin_lock(&po->bind_lock);
 
 	if (po->fanout) {
 		if (dev)
 			dev_put(dev);
 
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_unlock;
 	}
 
-	lock_sock(sk);
-
-	spin_lock(&po->bind_lock);
 	unregister_prot_hook(sk, true);
 
 	po->num = protocol;
@@ -2545,7 +2554,7 @@
 out_unlock:
 	spin_unlock(&po->bind_lock);
 	release_sock(sk);
-	return 0;
+	return ret;
 }
 
 /*
@@ -3176,14 +3185,19 @@
 
 		if (optlen != sizeof(val))
 			return -EINVAL;
-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
 		if (val > INT_MAX)
 			return -EINVAL;
-		po->tp_reserve = val;
-		return 0;
+		lock_sock(sk);
+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+			ret = -EBUSY;
+		} else {
+			po->tp_reserve = val;
+			ret = 0;
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_LOSS:
 	{
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 7a2a8a1..f256c96 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -115,6 +115,7 @@
 	bool use_dsp_gapless_mode;
 	struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX];
 	struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
+	bool is_in_use[MSM_FRONTEND_DAI_MAX];
 };
 
 struct msm_compr_audio {
@@ -965,11 +966,16 @@
 {
 	struct snd_compr_runtime *runtime = cstream->runtime;
 	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
-	struct msm_compr_audio *prtd;
+	struct msm_compr_audio *prtd = NULL;
 	struct msm_compr_pdata *pdata =
 			snd_soc_platform_get_drvdata(rtd->platform);
 
 	pr_debug("%s\n", __func__);
+	if (pdata->is_in_use[rtd->dai_link->be_id] == true) {
+		pr_err("%s: %s is already in use,err: %d ",
+			__func__, rtd->dai_link->cpu_dai_name, -EBUSY);
+		return -EBUSY;
+	}
 	prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
 	if (prtd == NULL) {
 		pr_err("Failed to allocate memory for msm_compr_audio\n");
@@ -981,7 +987,7 @@
 	pdata->cstream[rtd->dai_link->be_id] = cstream;
 	pdata->audio_effects[rtd->dai_link->be_id] =
 		 kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL);
-	if (!pdata->audio_effects[rtd->dai_link->be_id]) {
+	if (pdata->audio_effects[rtd->dai_link->be_id] == NULL) {
 		pr_err("%s: Could not allocate memory for effects\n", __func__);
 		pdata->cstream[rtd->dai_link->be_id] = NULL;
 		kfree(prtd);
@@ -989,10 +995,11 @@
 	}
 	pdata->dec_params[rtd->dai_link->be_id] =
 		 kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL);
-	if (!pdata->dec_params[rtd->dai_link->be_id]) {
+	if (pdata->dec_params[rtd->dai_link->be_id] == NULL) {
 		pr_err("%s: Could not allocate memory for dec params\n",
 			__func__);
 		kfree(pdata->audio_effects[rtd->dai_link->be_id]);
+		pdata->audio_effects[rtd->dai_link->be_id] = NULL;
 		pdata->cstream[rtd->dai_link->be_id] = NULL;
 		kfree(prtd);
 		return -ENOMEM;
@@ -1002,7 +1009,9 @@
 	if (!prtd->audio_client) {
 		pr_err("%s: Could not allocate memory for client\n", __func__);
 		kfree(pdata->audio_effects[rtd->dai_link->be_id]);
+		pdata->audio_effects[rtd->dai_link->be_id] = NULL;
 		kfree(pdata->dec_params[rtd->dai_link->be_id]);
+		pdata->dec_params[rtd->dai_link->be_id] = NULL;
 		pdata->cstream[rtd->dai_link->be_id] = NULL;
 		kfree(prtd);
 		return -ENOMEM;
@@ -1062,7 +1071,7 @@
 	} else {
 		pr_err("%s: Unsupported stream type", __func__);
 	}
-
+	pdata->is_in_use[rtd->dai_link->be_id] = true;
 	return 0;
 }
 
@@ -1155,11 +1164,15 @@
 	q6asm_audio_client_buf_free_contiguous(dir, ac);
 
 	q6asm_audio_client_free(ac);
-
-	kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
-	pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL;
-	kfree(pdata->dec_params[soc_prtd->dai_link->be_id]);
-	pdata->dec_params[soc_prtd->dai_link->be_id] = NULL;
+	if (pdata->audio_effects[soc_prtd->dai_link->be_id] != NULL) {
+		kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
+		pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL;
+	}
+	if (pdata->dec_params[soc_prtd->dai_link->be_id] != NULL) {
+		kfree(pdata->dec_params[soc_prtd->dai_link->be_id]);
+		pdata->dec_params[soc_prtd->dai_link->be_id] = NULL;
+	}
+	pdata->is_in_use[soc_prtd->dai_link->be_id] = false;
 	kfree(prtd);
 	runtime->private_data = NULL;
 
@@ -2636,6 +2649,7 @@
 		pdata->dec_params[i] = NULL;
 		pdata->cstream[i] = NULL;
 		pdata->ch_map[i] = NULL;
+		pdata->is_in_use[i] = false;
 	}
 
 	/*
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1b091e0..1d30f3e 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -222,6 +222,7 @@
 	struct usb_interface *usb_iface;
 	void *control_header;
 	int i, protocol;
+	int rest_bytes;
 
 	usb_iface = usb_ifnum_to_if(dev, ctrlif);
 	if (!usb_iface) {
@@ -248,6 +249,15 @@
 		return -EINVAL;
 	}
 
+	rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
+		control_header;
+
+	/* just to be sure -- this shouldn't hit at all */
+	if (rest_bytes <= 0) {
+		dev_err(&dev->dev, "invalid control header\n");
+		return -EINVAL;
+	}
+
 	switch (protocol) {
 	default:
 		snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
@@ -257,11 +267,21 @@
 	case UAC_VERSION_1: {
 		struct uac1_ac_header_descriptor *h1 = control_header;
 
+		if (rest_bytes < sizeof(*h1)) {
+			dev_err(&dev->dev, "too short v1 buffer descriptor\n");
+			return -EINVAL;
+		}
+
 		if (!h1->bInCollection) {
 			snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
 			return -EINVAL;
 		}
 
+		if (rest_bytes < h1->bLength) {
+			dev_err(&dev->dev, "invalid buffer length (v1)\n");
+			return -EINVAL;
+		}
+
 		if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
 			snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
 			return -EINVAL;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f7ad0a0..1e2620a 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2072,6 +2072,9 @@
 
 static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
 {
+	/* kill pending URBs */
+	snd_usb_mixer_disconnect(&mixer->list);
+
 	kfree(mixer->id_elems);
 	if (mixer->urb) {
 		kfree(mixer->urb->transfer_buffer);
@@ -2418,6 +2421,11 @@
 	struct usb_mixer_interface *mixer;
 
 	mixer = list_entry(p, struct usb_mixer_interface, list);
-	usb_kill_urb(mixer->urb);
-	usb_kill_urb(mixer->rc_urb);
+	if (mixer->disconnected)
+		return;
+	if (mixer->urb)
+		usb_kill_urb(mixer->urb);
+	if (mixer->rc_urb)
+		usb_kill_urb(mixer->rc_urb);
+	mixer->disconnected = true;
 }
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index aab80df..041b571 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -23,6 +23,7 @@
 
 	u8 audigy2nx_leds[3];
 	u8 xonar_u1_status;
+	bool disconnected;
 };
 
 #define MAX_CHANNELS	16	/* max logical channels */