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

Commit 34f2473a 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: Add checks to avoid OOB access"

parents 7b58bdf9 1c108062
Loading
Loading
Loading
Loading
+77 −16
Original line number Diff line number Diff line
@@ -933,6 +933,21 @@ static enum vidc_status hfi_parse_init_done_properties(
	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)) {

@@ -946,6 +961,10 @@ static enum vidc_status hfi_parse_init_done_properties(
				(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);
@@ -958,11 +977,14 @@ static enum vidc_status hfi_parse_init_done_properties(
				(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);
@@ -983,10 +1005,10 @@ static enum vidc_status hfi_parse_init_done_properties(
			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];
@@ -997,11 +1019,10 @@ static enum vidc_status hfi_parse_init_done_properties(
				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) +
@@ -1009,6 +1030,10 @@ static enum vidc_status hfi_parse_init_done_properties(
					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--;
@@ -1021,6 +1046,15 @@ static enum vidc_status hfi_parse_init_done_properties(
			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--;
@@ -1032,6 +1066,15 @@ static enum vidc_status hfi_parse_init_done_properties(
				(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);
@@ -1056,6 +1099,10 @@ static enum vidc_status hfi_parse_init_done_properties(
				(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,
@@ -1068,12 +1115,18 @@ static enum vidc_status hfi_parse_init_done_properties(
		}
		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--;
@@ -1081,6 +1134,9 @@ static enum vidc_status hfi_parse_init_done_properties(
		}
		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 +=
@@ -1094,8 +1150,13 @@ static enum vidc_status hfi_parse_init_done_properties(
				__func__, data_ptr, prop_id);
			break;
		}

		if (rem_bytes > next_offset) {
			rem_bytes -= next_offset;
			data_ptr += next_offset;
		} else {
			rem_bytes = 0;
		}
	}

	return status;