Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec12b494 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Avoid information leak while accessing the packet"

parents 0309ade5 146756d4
Loading
Loading
Loading
Loading
+83 −12
Original line number Diff line number Diff line
@@ -103,12 +103,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
	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_pkt_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;
@@ -116,17 +126,15 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
	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;
	enum msm_vidc_pixel_depth 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;
@@ -147,10 +155,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,

	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;
@@ -160,8 +176,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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;
@@ -172,8 +192,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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;
				/*
@@ -204,8 +228,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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 =
@@ -215,8 +243,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						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 =
@@ -231,9 +263,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						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;
@@ -244,8 +280,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						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;
@@ -253,8 +292,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					"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 *)
@@ -266,8 +309,13 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						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 *)
@@ -288,6 +336,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
				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,
@@ -747,7 +797,7 @@ static inline void copy_cap_prop(
}

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;
	struct msm_vidc_capability *capability;
@@ -757,6 +807,9 @@ static int hfi_fill_codec_info(u8 *data_ptr,
	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 =
@@ -764,6 +817,8 @@ static int hfi_fill_codec_info(u8 *data_ptr,
		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",
@@ -804,14 +859,22 @@ static int hfi_fill_codec_info(u8 *data_ptr,
	}
	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);
	}
@@ -1167,7 +1230,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
	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) {
@@ -1175,6 +1239,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
			"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);
@@ -1202,7 +1271,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
			"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--;
+65 −12
Original line number Diff line number Diff line
@@ -100,12 +100,22 @@ static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
	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_pkt_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, rem_size;
	struct hfi_frame_size *frame_sz;
	struct hfi_profile_level *profile_level;
	struct hfi_bit_depth *pixel_depth;
@@ -114,15 +124,11 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
	int prop_id;
	enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
	struct hfi_colour_space *colour_info;

	 /* Initialize pic_struct to unknown as default */
	event_notify.pic_struct = MSM_VIDC_PIC_STRUCT_UNKNOWN;

	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;
@@ -143,10 +149,18 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,

	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;
@@ -156,8 +170,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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;
@@ -166,8 +184,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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;
				/*
@@ -198,8 +220,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
					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 =
@@ -209,8 +235,12 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						pic_struct->progressive_only);
				data_ptr +=
					sizeof(struct hfi_pic_struct);
				rem_size -= sizeof(struct hfi_pic_struct);
				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;
@@ -221,6 +251,8 @@ static int hfi_process_sess_evt_seq_changed(u32 device_id,
						colour_info->colour_space);
				data_ptr +=
					sizeof(struct hfi_colour_space);
				rem_size -= sizeof(struct hfi_colour_space);
				break;
				break;
			default:
				dprintk(VIDC_ERR,
@@ -579,7 +611,7 @@ static inline void copy_cap_prop(
}

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;
	struct msm_vidc_capability *capability;
@@ -589,6 +621,9 @@ static int hfi_fill_codec_info(u8 *data_ptr,
	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 =
@@ -596,6 +631,8 @@ static int hfi_fill_codec_info(u8 *data_ptr,
		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",
@@ -636,14 +673,22 @@ static int hfi_fill_codec_info(u8 *data_ptr,
	}
	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);
	}
@@ -1003,7 +1048,8 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
	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;
	u32 codecs = 0, domain = 0;

@@ -1012,6 +1058,11 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
			"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);
@@ -1039,7 +1090,9 @@ enum vidc_status hfi_process_sys_init_done_prop_read(
			"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--;