Merge branch 'android-msm-marlin-3.18-ndr-factoryrom' into android-msm-marlin-3.18-nyc-mr1

Security January 2017.1

Change-Id: I324316cdb5874580139d8ccac645bb4fba49842f
diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module.c b/drivers/input/misc/vl53L0/stmvl53l0_module.c
index 0028e52..cc27309 100644
--- a/drivers/input/misc/vl53L0/stmvl53l0_module.c
+++ b/drivers/input/misc/vl53L0/stmvl53l0_module.c
@@ -2483,6 +2483,8 @@
                 if (!data->enable_ps_sensor)
                     stmvl53l0_start(data, 3, NORMAL_MODE);
 
+                memset(&RangingMeasurementData, 0, sizeof(RangingMeasurementData));
+
                 for (i = 0; i < RANGE_MEASUREMENT_TIMES;)
                 {
                     Status = papi_func_tbl->PerformSingleRangingMeasurement(vl53l0_dev, &RangingMeasurementData);
diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c
index 05f13b4..f7d5dbd 100644
--- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c
@@ -771,6 +771,21 @@
 DECLARE_COMPLETION(fwu_remove_complete);
 DEFINE_MUTEX(fwu_sysfs_mutex);
 
+/* Check offset + size <= bound.  true if in bounds, false otherwise. */
+static bool in_bounds(unsigned long offset, unsigned long size,
+		      unsigned long bound)
+{
+	if (offset > bound || size > bound) {
+		pr_err("%s: %lu or %lu > %lu\n", __func__, offset, size, bound);
+		return false;
+	}
+	if (offset > (bound - size)) {
+		pr_err("%s: %lu > %lu - %lu\n", __func__, offset, size, bound);
+		return false;
+	}
+	return true;
+}
+
 #ifdef HTC_FEATURE
 static uint32_t syn_crc(uint16_t *data, uint32_t len)
 {
@@ -966,8 +981,10 @@
 	return;
 }
 
-static void fwu_parse_partition_table(const unsigned char *partition_table,
-		struct block_count *blkcount, struct physical_address *phyaddr)
+static int fwu_parse_partition_table(const unsigned char *partition_table,
+				     unsigned long len,
+				     struct block_count *blkcount,
+				     struct physical_address *phyaddr)
 {
 	unsigned char ii;
 	unsigned char index;
@@ -979,6 +996,11 @@
 
 	for (ii = 0; ii < fwu->partitions; ii++) {
 		index = ii * 8 + 2;
+		if (!in_bounds(index, sizeof(*ptable), len)) {
+			pr_err("%s: %d/%d not in bounds\n", __func__, ii,
+			       fwu->partitions);
+			return -EINVAL;
+		}
 		ptable = (struct partition_table *)&partition_table[index];
 		partition_length = ptable->partition_length_15_8 << 8 |
 				ptable->partition_length_7_0;
@@ -987,7 +1009,7 @@
 		dev_dbg(rmi4_data->pdev->dev.parent,
 				"%s: Partition entry %d:\n",
 				__func__, ii);
-		for (offset = 0; offset < 8; offset++) {
+		for (offset = 0; offset < sizeof(*ptable); offset++) {
 			dev_dbg(rmi4_data->pdev->dev.parent,
 					"%s: 0x%02x\n",
 					__func__,
@@ -1077,16 +1099,17 @@
 		};
 	}
 
-	return;
+	return 0;
 }
 
-static void fwu_parse_image_header_10_utility(const unsigned char *image)
+static int fwu_parse_image_header_10_utility(const unsigned char *image)
 {
 	unsigned char ii;
 	unsigned char num_of_containers;
 	unsigned int addr;
 	unsigned int container_id;
 	unsigned int length;
+	unsigned int content_offset;
 	const unsigned char *content;
 	struct container_descriptor *descriptor;
 
@@ -1099,15 +1122,22 @@
 		if (ii >= MAX_UTILITY_PARAMS)
 			continue;
 		addr = le_to_uint(fwu->img.utility.data + (ii * 4));
+		if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size))
+			return -EINVAL;
 		descriptor = (struct container_descriptor *)(image + addr);
 		container_id = descriptor->container_id[0] |
 				descriptor->container_id[1] << 8;
-		content = image + le_to_uint(descriptor->content_address);
+		content_offset = le_to_uint(descriptor->content_address);
 		length = le_to_uint(descriptor->content_length);
+		if (!in_bounds(content_offset, length, fwu->image_size))
+			return -EINVAL;
+		content = image + content_offset;
 		switch (container_id) {
 		case UTILITY_PARAMETER_CONTAINER:
 			fwu->img.utility_param[ii].data = content;
 			fwu->img.utility_param[ii].size = length;
+			if (length < sizeof(content[0]))
+				return -EINVAL;
 			fwu->img.utility_param_id[ii] = content[0];
 			break;
 		default:
@@ -1115,28 +1145,36 @@
 		};
 	}
 
-	return;
+	return 0;
 }
 
-static void fwu_parse_image_header_10_bootloader(const unsigned char *image)
+static int fwu_parse_image_header_10_bootloader(const unsigned char *image)
 {
 	unsigned char ii;
 	unsigned char num_of_containers;
 	unsigned int addr;
 	unsigned int container_id;
 	unsigned int length;
+	unsigned int content_offset;
 	const unsigned char *content;
 	struct container_descriptor *descriptor;
 
+	if (fwu->img.bootloader.size < 4)
+		return -EINVAL;
 	num_of_containers = (fwu->img.bootloader.size - 4) / 4;
 
 	for (ii = 1; ii <= num_of_containers; ii++) {
 		addr = le_to_uint(fwu->img.bootloader.data + (ii * 4));
+		if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size))
+			return -EINVAL;
 		descriptor = (struct container_descriptor *)(image + addr);
 		container_id = descriptor->container_id[0] |
 				descriptor->container_id[1] << 8;
-		content = image + le_to_uint(descriptor->content_address);
+		content_offset = le_to_uint(descriptor->content_address);
 		length = le_to_uint(descriptor->content_length);
+		if (!in_bounds(content_offset, length, fwu->image_size))
+			return -EINVAL;
+		content = image + content_offset;
 		switch (container_id) {
 		case BL_IMAGE_CONTAINER:
 			fwu->img.bl_image.data = content;
@@ -1157,29 +1195,36 @@
 		};
 	}
 
-	return;
+	return 0;
 }
 
-static void fwu_parse_image_header_10(void)
+static int fwu_parse_image_header_10(void)
 {
 	unsigned char ii;
 	unsigned char num_of_containers;
 	unsigned int addr;
 	unsigned int offset;
+	unsigned int content_offset;
 	unsigned int container_id;
 	unsigned int length;
+	unsigned int image_size;
 	const unsigned char *image;
 	const unsigned char *content;
 	struct container_descriptor *descriptor;
 	struct image_header_10 *header;
 
 	image = fwu->image;
+	image_size = fwu->image_size;
+	if (image_size < sizeof(*header))
+		return -EINVAL;
 	header = (struct image_header_10 *)image;
 
 	fwu->img.checksum = le_to_uint(header->checksum);
 
 	/* address of top level container */
 	offset = le_to_uint(header->top_level_container_start_addr);
+	if (!in_bounds(offset, sizeof(*descriptor), image_size))
+		return -EINVAL;
 	descriptor = (struct container_descriptor *)(image + offset);
 
 	/* address of top level container content */
@@ -1187,13 +1232,20 @@
 	num_of_containers = le_to_uint(descriptor->content_length) / 4;
 
 	for (ii = 0; ii < num_of_containers; ii++) {
+		if (!in_bounds(offset, 4, image_size))
+			return -EINVAL;
 		addr = le_to_uint(image + offset);
 		offset += 4;
+		if (!in_bounds(addr, sizeof(*descriptor), image_size))
+			return -EINVAL;
 		descriptor = (struct container_descriptor *)(image + addr);
 		container_id = descriptor->container_id[0] |
 				descriptor->container_id[1] << 8;
-		content = image + le_to_uint(descriptor->content_address);
+		content_offset = le_to_uint(descriptor->content_address);
 		length = le_to_uint(descriptor->content_length);
+		if (!in_bounds(content_offset, length, image_size))
+			return -EINVAL;
+		content = image + content_offset;
 		switch (container_id) {
 		case UI_CONTAINER:
 		case CORE_CODE_CONTAINER:
@@ -1209,12 +1261,14 @@
 			fwu->img.bl_version = *content;
 			fwu->img.bootloader.data = content;
 			fwu->img.bootloader.size = length;
-			fwu_parse_image_header_10_bootloader(image);
+			if (fwu_parse_image_header_10_bootloader(image))
+				return -EINVAL;
 			break;
 		case UTILITY_CONTAINER:
 			fwu->img.utility.data = content;
 			fwu->img.utility.size = length;
-			fwu_parse_image_header_10_utility(image);
+			if (fwu_parse_image_header_10_utility(image))
+				return -EINVAL;
 			break;
 		case GUEST_CODE_CONTAINER:
 			fwu->img.contains_guest_code = true;
@@ -1239,6 +1293,8 @@
 			break;
 		case GENERAL_INFORMATION_CONTAINER:
 			fwu->img.contains_firmware_id = true;
+			if (length < 4 + 4)
+				return -EINVAL;
 			fwu->img.firmware_id = le_to_uint(content + 4);
 			break;
 		default:
@@ -1246,10 +1302,10 @@
 		}
 	}
 
-	return;
+	return 0;
 }
 
-static void fwu_parse_image_header_05_06(void)
+static int fwu_parse_image_header_05_06(void)
 {
 	int retval;
 	const unsigned char *image;
@@ -1257,6 +1313,8 @@
 	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
 
 	image = fwu->image;
+	if (fwu->image_size < sizeof(*header))
+		return -EINVAL;
 	header = (struct image_header_05_06 *)image;
 
 	fwu->img.checksum = le_to_uint(header->checksum);
@@ -1269,18 +1327,51 @@
 
 	fwu->img.ui_firmware.size = le_to_uint(header->firmware_size);
 	if (fwu->img.ui_firmware.size) {
-		fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET;
-		if (fwu->img.contains_bootloader)
-			fwu->img.ui_firmware.data += fwu->img.bootloader_size;
+		unsigned int ui_firmware_offset = IMAGE_AREA_OFFSET;
+
+		if (fwu->img.contains_bootloader) {
+			if (!in_bounds(ui_firmware_offset,
+				       fwu->img.bootloader_size,
+				       fwu->image_size)) {
+				return -EINVAL;
+			}
+			ui_firmware_offset += fwu->img.bootloader_size;
+		}
+		if (!in_bounds(ui_firmware_offset,
+			       fwu->img.ui_firmware.size,
+			       fwu->image_size)) {
+			return -EINVAL;
+		}
+		fwu->img.ui_firmware.data = image + ui_firmware_offset;
 	}
 
-	if ((fwu->img.bl_version == BL_V6) && header->options_tddi)
+	if ((fwu->img.bl_version == BL_V6) && header->options_tddi) {
+		if (!in_bounds(IMAGE_AREA_OFFSET,
+			       fwu->img.ui_firmware.size,
+			       fwu->image_size)) {
+			return -EINVAL;
+		}
 		fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET;
+	}
 
 	fwu->img.ui_config.size = le_to_uint(header->config_size);
 	if (fwu->img.ui_config.size) {
-		fwu->img.ui_config.data = fwu->img.ui_firmware.data +
+		unsigned int ui_firmware_end;
+
+		if (fwu->img.ui_firmware.data < image)
+			return -EINVAL;
+		if (!in_bounds(fwu->img.ui_firmware.data - image,
+			       fwu->img.ui_firmware.size,
+			       fwu->image_size)) {
+			return -EINVAL;
+		}
+		ui_firmware_end = fwu->img.ui_firmware.data - image +
 				fwu->img.ui_firmware.size;
+		if (!in_bounds(ui_firmware_end, fwu->img.ui_config.size,
+			       fwu->image_size)) {
+			return -EINVAL;
+		}
+		fwu->img.ui_config.data = image + ui_firmware_end;
 	}
 
 	if ((fwu->img.bl_version == BL_V5 && fwu->img.contains_bootloader) ||
@@ -1292,6 +1383,11 @@
 	if (fwu->img.contains_disp_config) {
 		fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr);
 		fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size);
+		if (!in_bounds(fwu->img.disp_config_offset,
+			       fwu->img.dp_config.size,
+			       fwu->image_size)) {
+			return -EINVAL;
+		}
 		fwu->img.dp_config.data = image + fwu->img.disp_config_offset;
 	} else {
 		retval = secure_memcpy(fwu->img.cstmr_product_id,
@@ -1323,28 +1419,41 @@
 	}
 	fwu->img.product_id[PRODUCT_ID_SIZE] = 0;
 
+	if (LOCKDOWN_SIZE > IMAGE_AREA_OFFSET)
+		return -EINVAL;
+	if (fwu->image_size < IMAGE_AREA_OFFSET)
+		return -EINVAL;
 	fwu->img.lockdown.size = LOCKDOWN_SIZE;
 	fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE;
 
-	return;
+	return 0;
 }
 
 static int fwu_parse_image_info(void)
 {
+	int parse_retval;
 	struct image_header_10 *header;
 	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
+	unsigned int image_size = 0;
 
 	header = (struct image_header_10 *)fwu->image;
-
+	if (!header)
+		return -EINVAL;
+	image_size = fwu->image_size;
+	if (image_size < sizeof(struct image_header_05_06) &&
+	    image_size < sizeof(struct image_header_10)) {
+		return -EINVAL;
+	}
+	/* This is clearing img, not image. */
 	memset(&fwu->img, 0x00, sizeof(fwu->img));
 
 	switch (header->major_header_version) {
 	case IMAGE_HEADER_VERSION_10:
-		fwu_parse_image_header_10();
+		parse_retval = fwu_parse_image_header_10();
 		break;
 	case IMAGE_HEADER_VERSION_05:
 	case IMAGE_HEADER_VERSION_06:
-		fwu_parse_image_header_05_06();
+		parse_retval = fwu_parse_image_header_05_06();
 		break;
 	default:
 		dev_err(rmi4_data->pdev->dev.parent,
@@ -1353,6 +1462,10 @@
 		return -EINVAL;
 	}
 
+	if (parse_retval != 0) {
+		return -EINVAL;
+	}
+
 	if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) {
 		if (!fwu->img.contains_flash_config) {
 			dev_err(rmi4_data->pdev->dev.parent,
@@ -1361,9 +1474,12 @@
 			return -EINVAL;
 		}
 
-		fwu_parse_partition_table(fwu->img.fl_config.data,
-				&fwu->img.blkcount, &fwu->img.phyaddr);
-
+		if (fwu_parse_partition_table(fwu->img.fl_config.data,
+					      fwu->img.fl_config.size,
+					      &fwu->img.blkcount,
+					      &fwu->img.phyaddr)) {
+			return -EINVAL;
+		}
 		fwu_compare_partition_tables();
 	} else {
 		fwu->new_partition_table = false;
@@ -1980,7 +2096,11 @@
 		return retval;
 	}
 
-	fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr);
+	if (fwu_parse_partition_table(ptable, fwu->partition_table_bytes,
+				      &fwu->blkcount, &fwu->phyaddr)) {
+		kfree(ptable);
+		return -EINVAL;
+	}
 
 	if (fwu->blkcount.dp_config)
 		fwu->flash_properties.has_disp_config = 1;
@@ -3209,6 +3329,9 @@
 	struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data;
 
 	utility_param_size = fwu->blkcount.utility_param * fwu->block_size;
+	/* See remaining_size below for reason for '4' */
+	if (utility_param_size < 4)
+		return -EINVAL;
 	retval = fwu_allocate_read_config_buf(utility_param_size);
 	if (retval < 0)
 		return retval;
@@ -4910,6 +5033,7 @@
 
 	rmi4_data->stay_awake = true;
 
+	memset(config_id, 0, sizeof(config_id));
 	if (fwu->bl_version == BL_V7)
 		config_id_size = V7_CONFIG_ID_SIZE;
 	else
@@ -4928,6 +5052,7 @@
 	}
 
 	memset(str_buf, 0, sizeof(str_buf));
+	memset(tmp_buf, 0, sizeof(tmp_buf));
 	for (ii = 0; ii < config_id_size; ii++) {
 		snprintf(tmp_buf, 3, "%02x ", config_id[ii]);
 		strlcat(str_buf, tmp_buf, sizeof(str_buf));
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index bf39738..a700f83 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -1559,11 +1559,13 @@
 			pr_err("a_ctrl->i2c_client.i2c_func_tbl NULL\n");
 			return -EINVAL;
 		}
+		mutex_lock(a_ctrl->actuator_mutex);
 		rc = msm_actuator_power_down(a_ctrl);
 		if (rc < 0) {
 			pr_err("%s:%d Actuator Power down failed\n",
 					__func__, __LINE__);
 		}
+		mutex_unlock(a_ctrl->actuator_mutex);
 		return msm_actuator_close(sd, NULL);
 	default:
 		return -ENOIOCTLCMD;
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index ad902db..56f9713 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2784,6 +2784,9 @@
 		ret = -EBUSY;
 		goto out;
 	}
+	ret = security_binder_set_context_mgr(proc->tsk);
+	if (ret < 0)
+		goto out;
 	if (uid_valid(binder_context_mgr_uid)) {
 		if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
 			pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
@@ -2849,9 +2852,6 @@
 		ret = binder_ioctl_set_ctx_mgr(filp);
 		if (ret)
 			goto err;
-		ret = security_binder_set_context_mgr(proc->tsk);
-		if (ret < 0)
-			goto err;
 		break;
 	case BINDER_THREAD_EXIT:
 		binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n",
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 8bbbb38..63e6b7d 100755
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -507,9 +507,9 @@
 	return 0;
 }
 
-struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len,
 			     size_t align, unsigned int heap_id_mask,
-			     unsigned int flags)
+			     unsigned int flags, bool grab_handle)
 {
 	struct ion_handle *handle;
 	struct ion_device *dev = client->dev;
@@ -604,6 +604,8 @@
 		return handle;
 
 	mutex_lock(&client->lock);
+	if (grab_handle)
+		ion_handle_get(handle);
 	ret = ion_handle_add(client, handle);
 	mutex_unlock(&client->lock);
 	if (ret) {
@@ -613,6 +615,13 @@
 
 	return handle;
 }
+
+struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+			     size_t align, unsigned int heap_id_mask,
+			     unsigned int flags)
+{
+	return __ion_alloc(client, len, align, heap_id_mask, flags, false);
+}
 EXPORT_SYMBOL(ion_alloc);
 
 static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
@@ -1488,10 +1497,10 @@
 	{
 		struct ion_handle *handle;
 
-		handle = ion_alloc(client, data.allocation.len,
+		handle = __ion_alloc(client, data.allocation.len,
 						data.allocation.align,
 						data.allocation.heap_id_mask,
-						data.allocation.flags);
+						data.allocation.flags, true);
 		if (IS_ERR(handle))
 			return PTR_ERR(handle);
 
@@ -1568,11 +1577,15 @@
 
 	if (dir & _IOC_READ) {
 		if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
-			if (cleanup_handle)
+			if (cleanup_handle) {
 				ion_free(client, cleanup_handle);
+				ion_handle_put(cleanup_handle);
+			}
 			return -EFAULT;
 		}
 	}
+	if (cleanup_handle)
+		ion_handle_put(cleanup_handle);
 	return ret;
 }
 
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c
index 9d7f596..f353888 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2744,7 +2744,7 @@
       case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
       {
          hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-         struct station_info staInfo;
+         struct station_info *stainfo;
 
          pr_info ( "IBSS New Peer indication from SME "
                     "with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d",
@@ -2779,13 +2779,20 @@
                vosStatus, vosStatus );
          }
          pHddStaCtx->ibss_sta_generation++;
-         memset(&staInfo, 0, sizeof(staInfo));
-         staInfo.filled = 0;
-         staInfo.generation = pHddStaCtx->ibss_sta_generation;
+         stainfo = vos_mem_malloc(sizeof(*stainfo));
+         if (stainfo == NULL) {
+             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                     "memory allocation for station_info failed");
+             return eHAL_STATUS_FAILED_ALLOC;
+         }
+         memset(stainfo, 0, sizeof(*stainfo));
+         stainfo->filled = 0;
+         stainfo->generation = pHddStaCtx->ibss_sta_generation;
 
          cfg80211_new_sta(pAdapter->dev,
                       (const u8 *)pRoamInfo->peerMac,
-                      &staInfo, GFP_KERNEL);
+                      stainfo, GFP_KERNEL);
+         vos_mem_free(stainfo);
 
          if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType
             ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
index 013a2db..e45b704 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2871,7 +2871,7 @@
 	struct hdd_ext_scan_context *context;
 	uint32_t request_id;
 	char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1];
-	int ssid_len;
+        int ssid_len, ssid_length;
 	eHalStatus status;
 	int i, rem, retval;
 	unsigned long rc;
@@ -2950,12 +2950,16 @@
 			hddLog(LOGE, FL("attr ssid failed"));
 			goto fail;
 		}
-		nla_memcpy(ssid_string,
+                ssid_length = nla_strlcpy(ssid_string,
 			   tb2[PARAM_SSID],
 			   sizeof(ssid_string));
 		hddLog(LOG1, FL("SSID %s"),
 		       ssid_string);
 		ssid_len = strlen(ssid_string);
+                if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) {
+                        hddLog(LOGE, FL("Invalid ssid length"));
+                        goto fail;
+                }
 		memcpy(request->ssids[i].ssid.ssId, ssid_string, ssid_len);
 		request->ssids[i].ssid.length = ssid_len;
 
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
index 4ac29d4..a1f30c2 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1825,21 +1825,27 @@
                                           HDD_SAP_WAKE_LOCK_DURATION,
                                           WIFI_POWER_EVENT_WAKELOCK_SAP);
             {
-               struct station_info staInfo;
                v_U16_t iesLen =  pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
 
-               memset(&staInfo, 0, sizeof(staInfo));
                if (iesLen <= MAX_ASSOC_IND_IE_LEN )
                {
-                  staInfo.assoc_req_ies =
+                  struct station_info *stainfo;
+                  stainfo = vos_mem_malloc(sizeof(*stainfo));
+                  if (stainfo == NULL) {
+                      hddLog(LOGE, FL("alloc station_info failed"));
+                      return VOS_STATUS_E_NOMEM;
+                  }
+                  memset(stainfo, 0, sizeof(*stainfo));
+                  stainfo->assoc_req_ies =
                      (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
-                  staInfo.assoc_req_ies_len = iesLen;
+                  stainfo->assoc_req_ies_len = iesLen;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) || defined(WITH_BACKPORTS)
-                  staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
+                  stainfo->filled |= STATION_INFO_ASSOC_REQ_IES;
 #endif
                   cfg80211_new_sta(dev,
                         (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
-                        &staInfo, GFP_KERNEL);
+                        stainfo, GFP_KERNEL);
+                  vos_mem_free(stainfo);
                }
                else
                {
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
index b6494ca..95fde5e 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c
@@ -406,10 +406,11 @@
  *
  * Return: A pointer to the OCB configuration struct, NULL on failure.
  */
-static struct sir_ocb_config *hdd_ocb_config_new(int num_channels,
-						 int num_schedule,
-						 int ndl_chan_list_len,
-						 int ndl_active_state_list_len)
+static
+struct sir_ocb_config *hdd_ocb_config_new(uint32_t num_channels,
+					  uint32_t num_schedule,
+					  uint32_t ndl_chan_list_len,
+					  uint32_t ndl_active_state_list_len)
 {
 	struct sir_ocb_config *ret = 0;
 	uint32_t len;
@@ -903,7 +904,7 @@
 	void *def_tx_param = NULL;
 	uint32_t def_tx_param_size = 0;
 	int i;
-	int channel_count, schedule_size;
+	uint32_t channel_count, schedule_size;
 	struct sir_ocb_config *config;
 	int rc = -EINVAL;
 	uint8_t *mac_addr;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 01eab13..b7e1e224 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1449,10 +1449,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/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 0fc5cfe..7d370a6 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1693,14 +1693,13 @@
 	    !cpumask_test_cpu(cpu_id, buffer->cpumask))
 		return size;
 
-	size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
-	size *= BUF_PAGE_SIZE;
+	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
 
 	/* we need a minimum of two pages */
-	if (size < BUF_PAGE_SIZE * 2)
-		size = BUF_PAGE_SIZE * 2;
+	if (nr_pages < 2)
+		nr_pages = 2;
 
-	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+	size = nr_pages * BUF_PAGE_SIZE;
 
 	/*
 	 * Don't succeed if resizing is disabled, as a reader might be
diff --git a/mm/memory.c b/mm/memory.c
index 62b30f2..0abbdd2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2630,6 +2630,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_SIGSEGV;
@@ -3034,6 +3038,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);
@@ -3199,11 +3206,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);
 		}
diff --git a/sound/core/info.c b/sound/core/info.c
index 418b4ec..a4af0ba 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -253,6 +253,7 @@
 	struct snd_info_buffer *buf;
 	ssize_t size = 0;
 	loff_t pos;
+	unsigned long realloc_size;
 
 	data = file->private_data;
 	if (snd_BUG_ON(!data))
@@ -261,7 +262,8 @@
 	pos = *offset;
 	if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
 		return -EIO;
-	if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
+	realloc_size = (unsigned long) pos + (unsigned long) count;
+	if (realloc_size < (unsigned long) pos || realloc_size > UINT_MAX)
 		return -EIO;
 	switch (entry->content) {
 	case SNDRV_INFO_CONTENT_TEXT: