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

Commit 4461eef6 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 c9b07721 931bff86
Loading
Loading
Loading
Loading
+64 −10
Original line number Diff line number Diff line
@@ -99,12 +99,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,11 +124,9 @@ static int hfi_process_sess_evt_seq_changed(u32 device_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;
@@ -139,10 +147,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;
@@ -152,8 +168,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;
@@ -162,8 +182,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;
				/*
@@ -194,8 +218,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 =
@@ -205,8 +233,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;
@@ -217,6 +249,7 @@ 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;
			default:
				dprintk(VIDC_ERR,
@@ -574,7 +607,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;
@@ -584,6 +617,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 =
@@ -591,6 +627,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",
@@ -631,14 +669,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);
	}
@@ -997,7 +1043,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;

@@ -1006,6 +1053,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);
@@ -1033,7 +1085,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--;