Merge branch 'android-msm-floral-4.14-qt' into android-msm-floral-4.14-qt-qpr1

Feb 2020.1

Bug: 145881255
Change-Id: I2b08dcb2aee3ea04d691019e336c3e37ec0d97e4
Signed-off-by: Harrison Lingren <hlingren@google.com>
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index f78c343..52ec48d 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -104,12 +104,22 @@
 	return MSM_VIDC_BIT_DEPTH_UNSUPPORTED;
 }
 
+static inline int validate_pkt_size(u32 rem_size, u32 msg_size)
+{
+	if (rem_size < msg_size) {
+		dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n",
+			__func__, rem_size);
+		return false;
+	}
+	return true;
+}
+
 static int hfi_process_sess_evt_seq_changed(u32 device_id,
 		struct hfi_msg_event_notify_packet *pkt,
 		struct msm_vidc_cb_info *info)
 {
 	struct msm_vidc_cb_event event_notify = {0};
-	int num_properties_changed;
+	u32 num_properties_changed;
 	struct hfi_frame_size *frame_sz;
 	struct hfi_profile_level *profile_level;
 	struct hfi_bit_depth *pixel_depth;
@@ -117,17 +127,15 @@
 	struct hfi_buffer_requirements *buf_req;
 	struct hfi_index_extradata_input_crop_payload *crop_info;
 	struct hfi_dpb_counts *dpb_counts;
-	u32 entropy_mode = 0;
+	u32 rem_size, entropy_mode = 0;
 	u8 *data_ptr;
 	int prop_id;
 	int luma_bit_depth, chroma_bit_depth;
 	struct hfi_colour_space *colour_info;
 
-	if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) {
-		dprintk(VIDC_ERR,
-				"hal_process_session_init_done: bad_pkt_size\n");
+	if (!validate_pkt_size(pkt->size,
+			       sizeof(struct hfi_msg_event_notify_packet)))
 		return -E2BIG;
-	}
 
 	event_notify.device_id = device_id;
 	event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
@@ -148,10 +156,18 @@
 
 	if (num_properties_changed) {
 		data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
+		rem_size = pkt->size - sizeof(struct
+				hfi_msg_event_notify_packet) + sizeof(u32);
 		do {
+			if (!validate_pkt_size(rem_size, sizeof(u32)))
+				return -E2BIG;
 			prop_id = (int) *((u32 *)data_ptr);
+			rem_size -= sizeof(u32);
 			switch (prop_id) {
 			case HFI_PROPERTY_PARAM_FRAME_SIZE:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_frame_size)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				frame_sz =
 					(struct hfi_frame_size *) data_ptr;
@@ -161,8 +177,12 @@
 					frame_sz->height, frame_sz->width);
 				data_ptr +=
 					sizeof(struct hfi_frame_size);
+				rem_size -= sizeof(struct hfi_frame_size);
 				break;
 			case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_profile_level)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				profile_level =
 					(struct hfi_profile_level *) data_ptr;
@@ -173,8 +193,12 @@
 					profile_level->level);
 				data_ptr +=
 					sizeof(struct hfi_profile_level);
+				rem_size -= sizeof(struct hfi_profile_level);
 				break;
 			case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_bit_depth)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				pixel_depth = (struct hfi_bit_depth *) data_ptr;
 				/*
@@ -205,8 +229,12 @@
 					event_notify.bit_depth, luma_bit_depth,
 					chroma_bit_depth);
 				data_ptr += sizeof(struct hfi_bit_depth);
+				rem_size -= sizeof(struct hfi_bit_depth);
 				break;
 			case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_pic_struct)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				pic_struct = (struct hfi_pic_struct *) data_ptr;
 				event_notify.pic_struct =
@@ -216,8 +244,12 @@
 						pic_struct->progressive_only);
 				data_ptr +=
 					sizeof(struct hfi_pic_struct);
+				rem_size -= sizeof(struct hfi_pic_struct);
 				break;
 			case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_dpb_counts)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				dpb_counts = (struct hfi_dpb_counts *) data_ptr;
 				event_notify.max_dpb_count =
@@ -232,9 +264,13 @@
 						dpb_counts->max_ref_count,
 						dpb_counts->max_dec_buffering);
 				data_ptr +=
-					sizeof(struct hfi_pic_struct);
+					sizeof(struct hfi_dpb_counts);
+				rem_size -= sizeof(struct hfi_dpb_counts);
 				break;
 			case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_colour_space)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				colour_info =
 					(struct hfi_colour_space *) data_ptr;
@@ -245,8 +281,11 @@
 						colour_info->colour_space);
 				data_ptr +=
 					sizeof(struct hfi_colour_space);
+				rem_size -= sizeof(struct hfi_colour_space);
 				break;
 			case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
+				if (!validate_pkt_size(rem_size, sizeof(u32)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				entropy_mode = *(u32 *)data_ptr;
 				event_notify.entropy_mode = entropy_mode;
@@ -254,8 +293,12 @@
 					"Entropy Mode: 0x%x\n", entropy_mode);
 				data_ptr +=
 					sizeof(u32);
+				rem_size -= sizeof(u32);
 				break;
 			case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+					hfi_buffer_requirements)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				buf_req =
 					(struct hfi_buffer_requirements *)
@@ -267,8 +310,13 @@
 						event_notify.capture_buf_count);
 				data_ptr +=
 					sizeof(struct hfi_buffer_requirements);
+				rem_size -=
+					sizeof(struct hfi_buffer_requirements);
 				break;
 			case HFI_INDEX_EXTRADATA_INPUT_CROP:
+				if (!validate_pkt_size(rem_size, sizeof(struct
+				     hfi_index_extradata_input_crop_payload)))
+					return -E2BIG;
 				data_ptr = data_ptr + sizeof(u32);
 				crop_info = (struct
 				hfi_index_extradata_input_crop_payload *)
@@ -289,6 +337,8 @@
 				data_ptr +=
 					sizeof(struct
 					hfi_index_extradata_input_crop_payload);
+				rem_size -= sizeof(struct
+					hfi_index_extradata_input_crop_payload);
 				break;
 			default:
 				dprintk(VIDC_ERR,
@@ -742,7 +792,7 @@
 }
 
 static int hfi_fill_codec_info(u8 *data_ptr,
-		struct vidc_hal_sys_init_done *sys_init_done)
+		struct vidc_hal_sys_init_done *sys_init_done, u32 rem_size)
 {
 	u32 i;
 	u32 codecs = 0, codec_count = 0, size = 0;
@@ -753,6 +803,9 @@
 	if (prop_id ==  HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
 		struct hfi_codec_supported *prop;
 
+		if (!validate_pkt_size(rem_size - sizeof(u32),
+				       sizeof(struct hfi_codec_supported)))
+			return -E2BIG;
 		data_ptr = data_ptr + sizeof(u32);
 		prop = (struct hfi_codec_supported *) data_ptr;
 		sys_init_done->dec_codec_supported =
@@ -760,6 +813,8 @@
 		sys_init_done->enc_codec_supported =
 			prop->encoder_codec_supported;
 		size = sizeof(struct hfi_codec_supported) + sizeof(u32);
+		rem_size -=
+			sizeof(struct hfi_codec_supported) + sizeof(u32);
 	} else {
 		dprintk(VIDC_WARN,
 			"%s: prop_id %#x, expected codec_supported property\n",
@@ -800,14 +855,22 @@
 	}
 	sys_init_done->codec_count = codec_count;
 
+	if (!validate_pkt_size(rem_size, sizeof(u32)))
+		return -E2BIG;
 	prop_id = *((u32 *)(orig_data_ptr + size));
 	if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
-		struct hfi_max_sessions_supported *prop =
-			(struct hfi_max_sessions_supported *)
+		struct hfi_max_sessions_supported *prop;
+
+		if (!validate_pkt_size(rem_size - sizeof(u32), sizeof(struct
+				hfi_max_sessions_supported)))
+			return -E2BIG;
+		prop = (struct hfi_max_sessions_supported *)
 			(orig_data_ptr + size + sizeof(u32));
 
 		sys_init_done->max_sessions_supported = prop->max_sessions;
 		size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
+		rem_size -=
+			sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
 		dprintk(VIDC_DBG, "max_sessions_supported %d\n",
 				prop->max_sessions);
 	}
@@ -930,6 +993,21 @@
 	u32 prop_id, next_offset;
 	u32 codecs = 0, domain = 0;
 
+#define VALIDATE_PROPERTY_STRUCTURE_SIZE(pkt_size, property_size) ({\
+		if (pkt_size < property_size) { \
+			status = VIDC_ERR_BAD_PARAM; \
+			break; \
+		} \
+})
+
+#define VALIDATE_PROPERTY_PAYLOAD_SIZE(pkt_size, payload_size, \
+		property_count) ({\
+		if (pkt_size/payload_size < property_count) { \
+			status = VIDC_ERR_BAD_PARAM; \
+			break; \
+		} \
+})
+
 	while (status == VIDC_ERR_NONE && num_properties &&
 			rem_bytes >= sizeof(u32)) {
 
@@ -943,6 +1021,10 @@
 				(struct hfi_codec_mask_supported *)
 				(data_ptr + next_offset);
 
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+
 			codecs = prop->codecs;
 			domain = prop->video_domains;
 			next_offset += sizeof(struct hfi_codec_mask_supported);
@@ -955,11 +1037,14 @@
 				(struct hfi_capability_supported_info *)
 				(data_ptr + next_offset);
 
-			if ((rem_bytes - next_offset) < prop->num_capabilities *
-				sizeof(struct hfi_capability_supported)) {
-				status = VIDC_ERR_BAD_PARAM;
-				break;
-			}
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+			VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+					next_offset - sizeof(u32),
+					sizeof(struct hfi_capability_supported),
+					prop->num_capabilities);
+
 			next_offset += sizeof(u32) +
 				prop->num_capabilities *
 				sizeof(struct hfi_capability_supported);
@@ -980,10 +1065,10 @@
 			char *fmt_ptr;
 			struct hfi_uncompressed_plane_info *plane_info;
 
-			if ((rem_bytes - next_offset) < sizeof(*prop)) {
-				status = VIDC_ERR_BAD_PARAM;
-				break;
-			}
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+
 			num_format_entries = prop->format_entries;
 			next_offset = sizeof(*prop);
 			fmt_ptr = (char *)&prop->rg_format_info[0];
@@ -994,11 +1079,10 @@
 				plane_info =
 				(struct hfi_uncompressed_plane_info *) fmt_ptr;
 
-				if ((rem_bytes - next_offset) <
-						sizeof(*plane_info)) {
-					status = VIDC_ERR_BAD_PARAM;
-					break;
-				}
+				VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+						next_offset,
+						sizeof(*plane_info));
+
 				bytes_to_skip = sizeof(*plane_info) -
 					sizeof(struct
 					hfi_uncompressed_plane_constraints) +
@@ -1006,6 +1090,10 @@
 					sizeof(struct
 					hfi_uncompressed_plane_constraints);
 
+				VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+						next_offset,
+						bytes_to_skip);
+
 				fmt_ptr += bytes_to_skip;
 				next_offset += bytes_to_skip;
 				num_format_entries--;
@@ -1018,6 +1106,15 @@
 			struct hfi_properties_supported *prop =
 				(struct hfi_properties_supported *)
 				(data_ptr + next_offset);
+
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+			VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+					next_offset - sizeof(*prop) +
+					sizeof(u32), sizeof(u32),
+					prop->num_properties);
+
 			next_offset += sizeof(*prop) - sizeof(u32)
 				+ prop->num_properties * sizeof(u32);
 			num_properties--;
@@ -1029,6 +1126,15 @@
 				(struct hfi_profile_level_supported *)
 				(data_ptr + next_offset);
 
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+			VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
+					next_offset -
+					sizeof(u32),
+					sizeof(struct hfi_profile_level),
+					prop->profile_count);
+
 			next_offset += sizeof(u32) +
 				prop->profile_count *
 				sizeof(struct hfi_profile_level);
@@ -1053,6 +1159,10 @@
 				(struct hfi_nal_stream_format_supported *)
 					(data_ptr + next_offset);
 
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(*prop));
+
 			copy_nal_stream_format_caps_to_sessions(
 					prop->nal_stream_format_supported,
 					capabilities, num_sessions,
@@ -1065,12 +1175,18 @@
 		}
 		case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
 		{
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(u32));
 			next_offset += sizeof(u32);
 			num_properties--;
 			break;
 		}
 		case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
 		{
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(struct hfi_intra_refresh));
 			next_offset +=
 				sizeof(struct hfi_intra_refresh);
 			num_properties--;
@@ -1078,6 +1194,9 @@
 		}
 		case HFI_PROPERTY_TME_VERSION_SUPPORTED:
 		{
+			VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
+					next_offset,
+					sizeof(u32));
 			capabilities->tme_version =
 				*((u32 *)(data_ptr + next_offset));
 			next_offset +=
@@ -1091,8 +1210,13 @@
 				__func__, data_ptr, prop_id);
 			break;
 		}
-		rem_bytes -= next_offset;
-		data_ptr += next_offset;
+
+		if (rem_bytes > next_offset) {
+			rem_bytes -= next_offset;
+			data_ptr += next_offset;
+		} else {
+			rem_bytes = 0;
+		}
 	}
 
 	return status;
@@ -1103,7 +1227,8 @@
 	struct vidc_hal_sys_init_done *sys_init_done)
 {
 	enum vidc_status status = VIDC_ERR_NONE;
-	u32 rem_bytes, bytes_read, num_properties;
+	int bytes_read;
+	u32 rem_bytes, num_properties;
 	u8 *data_ptr;
 
 	if (!pkt || !sys_init_done) {
@@ -1111,6 +1236,11 @@
 			"hfi_msg_sys_init_done: Invalid input\n");
 		return VIDC_ERR_FAIL;
 	}
+	if (pkt->size < sizeof(struct hfi_msg_sys_init_done_packet)) {
+		dprintk(VIDC_ERR, "%s: bad_packet_size: %d\n",
+			__func__, pkt->size);
+		return VIDC_ERR_FAIL;
+	}
 
 	rem_bytes = pkt->size - sizeof(struct
 			hfi_msg_sys_init_done_packet) + sizeof(u32);
@@ -1138,7 +1268,9 @@
 			"Venus didn't set any properties in SYS_INIT_DONE");
 		return status;
 	}
-	bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
+	bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done, rem_bytes);
+	if (bytes_read < 0)
+		return VIDC_ERR_FAIL;
 	data_ptr += bytes_read;
 	rem_bytes -= bytes_read;
 	num_properties--;
diff --git a/drivers/soc/qcom/icnss_qmi.c b/drivers/soc/qcom/icnss_qmi.c
index c35149d..232ccb5 100644
--- a/drivers/soc/qcom/icnss_qmi.c
+++ b/drivers/soc/qcom/icnss_qmi.c
@@ -141,7 +141,7 @@
 	for (i = 0; i < resp->mem_region_info_len; i++) {
 
 		if (resp->mem_region_info[i].size > priv->msa_mem_size ||
-		    resp->mem_region_info[i].region_addr > max_mapped_addr ||
+		    resp->mem_region_info[i].region_addr >= max_mapped_addr ||
 		    resp->mem_region_info[i].region_addr < priv->msa_pa ||
 		    resp->mem_region_info[i].size +
 		    resp->mem_region_info[i].region_addr > max_mapped_addr) {