msm: vidc: Add checks to avoid OOB access
validate structures and payload sizes in the packet against packet size to avoid OOB access. Change-Id: Id44e5c6be4dde3e6545d453f5edd3219776a4e58 Signed-off-by: Manikanta Kanamarlapudi <kmanikan@codeaurora.org> Signed-off-by: Sanjay Singh <sisanj@codeaurora.org>
This commit is contained in:
parent
c748783b7b
commit
1fff932af1
1 changed files with 93 additions and 18 deletions
|
@ -839,6 +839,21 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
enum vidc_status status = VIDC_ERR_NONE;
|
enum vidc_status status = VIDC_ERR_NONE;
|
||||||
u32 prop_id, next_offset;
|
u32 prop_id, next_offset;
|
||||||
|
|
||||||
|
#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 &&
|
while (status == VIDC_ERR_NONE && num_properties &&
|
||||||
rem_bytes >= sizeof(u32)) {
|
rem_bytes >= sizeof(u32)) {
|
||||||
|
|
||||||
|
@ -852,6 +867,10 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
(struct hfi_codec_mask_supported *)
|
(struct hfi_codec_mask_supported *)
|
||||||
(data_ptr + next_offset);
|
(data_ptr + next_offset);
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(*prop));
|
||||||
|
|
||||||
codecs = prop->codecs;
|
codecs = prop->codecs;
|
||||||
domain = prop->video_domains;
|
domain = prop->video_domains;
|
||||||
next_offset += sizeof(struct hfi_codec_mask_supported);
|
next_offset += sizeof(struct hfi_codec_mask_supported);
|
||||||
|
@ -864,11 +883,14 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
(struct hfi_capability_supported_info *)
|
(struct hfi_capability_supported_info *)
|
||||||
(data_ptr + next_offset);
|
(data_ptr + next_offset);
|
||||||
|
|
||||||
if ((rem_bytes - next_offset) < prop->num_capabilities *
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
sizeof(struct hfi_capability_supported)) {
|
next_offset,
|
||||||
status = VIDC_ERR_BAD_PARAM;
|
sizeof(*prop));
|
||||||
break;
|
VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
|
||||||
}
|
next_offset - sizeof(u32),
|
||||||
|
sizeof(struct hfi_capability_supported),
|
||||||
|
prop->num_capabilities);
|
||||||
|
|
||||||
next_offset += sizeof(u32) +
|
next_offset += sizeof(u32) +
|
||||||
prop->num_capabilities *
|
prop->num_capabilities *
|
||||||
sizeof(struct hfi_capability_supported);
|
sizeof(struct hfi_capability_supported);
|
||||||
|
@ -889,10 +911,10 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
char *fmt_ptr;
|
char *fmt_ptr;
|
||||||
struct hfi_uncompressed_plane_info *plane_info;
|
struct hfi_uncompressed_plane_info *plane_info;
|
||||||
|
|
||||||
if ((rem_bytes - next_offset) < sizeof(*prop)) {
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
status = VIDC_ERR_BAD_PARAM;
|
next_offset,
|
||||||
break;
|
sizeof(*prop));
|
||||||
}
|
|
||||||
num_format_entries = prop->format_entries;
|
num_format_entries = prop->format_entries;
|
||||||
next_offset = sizeof(*prop);
|
next_offset = sizeof(*prop);
|
||||||
fmt_ptr = (char *)&prop->rg_format_info[0];
|
fmt_ptr = (char *)&prop->rg_format_info[0];
|
||||||
|
@ -902,11 +924,10 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
plane_info =
|
plane_info =
|
||||||
(struct hfi_uncompressed_plane_info *) fmt_ptr;
|
(struct hfi_uncompressed_plane_info *) fmt_ptr;
|
||||||
|
|
||||||
if ((rem_bytes - next_offset) <
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
sizeof(*plane_info)) {
|
next_offset,
|
||||||
status = VIDC_ERR_BAD_PARAM;
|
sizeof(*plane_info));
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytes_to_skip = sizeof(*plane_info) -
|
bytes_to_skip = sizeof(*plane_info) -
|
||||||
sizeof(struct
|
sizeof(struct
|
||||||
hfi_uncompressed_plane_constraints) +
|
hfi_uncompressed_plane_constraints) +
|
||||||
|
@ -914,6 +935,10 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
sizeof(struct
|
sizeof(struct
|
||||||
hfi_uncompressed_plane_constraints);
|
hfi_uncompressed_plane_constraints);
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
bytes_to_skip);
|
||||||
|
|
||||||
fmt_ptr += bytes_to_skip;
|
fmt_ptr += bytes_to_skip;
|
||||||
next_offset += bytes_to_skip;
|
next_offset += bytes_to_skip;
|
||||||
num_format_entries--;
|
num_format_entries--;
|
||||||
|
@ -926,6 +951,15 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
struct hfi_properties_supported *prop =
|
struct hfi_properties_supported *prop =
|
||||||
(struct hfi_properties_supported *)
|
(struct hfi_properties_supported *)
|
||||||
(data_ptr + next_offset);
|
(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)
|
next_offset += sizeof(*prop) - sizeof(u32)
|
||||||
+ prop->num_properties * sizeof(u32);
|
+ prop->num_properties * sizeof(u32);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
|
@ -942,8 +976,19 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
(struct hfi_profile_level_supported *)
|
(struct hfi_profile_level_supported *)
|
||||||
(data_ptr + next_offset);
|
(data_ptr + next_offset);
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(*prop));
|
||||||
|
|
||||||
ptr = (char *) &prop->rg_profile_level[0];
|
ptr = (char *) &prop->rg_profile_level[0];
|
||||||
prof_count = prop->profile_count;
|
prof_count = prop->profile_count;
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
|
||||||
|
next_offset -
|
||||||
|
sizeof(u32),
|
||||||
|
sizeof(struct hfi_profile_level),
|
||||||
|
prop->profile_count);
|
||||||
|
|
||||||
next_offset += sizeof(u32);
|
next_offset += sizeof(u32);
|
||||||
|
|
||||||
if (prof_count > MAX_PROFILE_COUNT) {
|
if (prof_count > MAX_PROFILE_COUNT) {
|
||||||
|
@ -970,6 +1015,9 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
}
|
}
|
||||||
case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
|
case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
|
||||||
{
|
{
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(struct hfi_interlace_format_supported));
|
||||||
next_offset +=
|
next_offset +=
|
||||||
sizeof(struct hfi_interlace_format_supported);
|
sizeof(struct hfi_interlace_format_supported);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
|
@ -977,6 +1025,9 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
}
|
}
|
||||||
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
|
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
|
||||||
{
|
{
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(struct hfi_nal_stream_format_supported));
|
||||||
next_offset +=
|
next_offset +=
|
||||||
sizeof(struct hfi_nal_stream_format_supported);
|
sizeof(struct hfi_nal_stream_format_supported);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
|
@ -984,18 +1035,27 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
}
|
}
|
||||||
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
|
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
|
||||||
{
|
{
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(u32));
|
||||||
next_offset += sizeof(u32);
|
next_offset += sizeof(u32);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
|
case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
|
||||||
{
|
{
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(u32));
|
||||||
next_offset += sizeof(u32);
|
next_offset += sizeof(u32);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
|
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
|
||||||
{
|
{
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(struct hfi_intra_refresh));
|
||||||
next_offset +=
|
next_offset +=
|
||||||
sizeof(struct hfi_intra_refresh);
|
sizeof(struct hfi_intra_refresh);
|
||||||
num_properties--;
|
num_properties--;
|
||||||
|
@ -1007,15 +1067,25 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
(struct hfi_buffer_alloc_mode_supported *)
|
(struct hfi_buffer_alloc_mode_supported *)
|
||||||
(data_ptr + next_offset);
|
(data_ptr + next_offset);
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_STRUCTURE_SIZE(rem_bytes -
|
||||||
|
next_offset,
|
||||||
|
sizeof(*prop));
|
||||||
|
next_offset +=
|
||||||
|
sizeof(struct hfi_buffer_alloc_mode_supported);
|
||||||
if (prop->num_entries >= 32) {
|
if (prop->num_entries >= 32) {
|
||||||
dprintk(VIDC_ERR,
|
dprintk(VIDC_ERR,
|
||||||
"%s - num_entries: %d from f/w seems suspect\n",
|
"%s - num_entries: %d from f/w seems suspect\n",
|
||||||
__func__, prop->num_entries);
|
__func__, prop->num_entries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALIDATE_PROPERTY_PAYLOAD_SIZE(rem_bytes -
|
||||||
|
next_offset +
|
||||||
|
sizeof(u32),
|
||||||
|
sizeof(u32),
|
||||||
|
prop->num_entries);
|
||||||
next_offset +=
|
next_offset +=
|
||||||
sizeof(struct hfi_buffer_alloc_mode_supported) -
|
prop->num_entries * sizeof(u32) - sizeof(u32);
|
||||||
sizeof(u32) + prop->num_entries * sizeof(u32);
|
|
||||||
|
|
||||||
copy_alloc_mode_to_sessions(prop,
|
copy_alloc_mode_to_sessions(prop,
|
||||||
capabilities, num_sessions,
|
capabilities, num_sessions,
|
||||||
|
@ -1030,8 +1100,13 @@ static enum vidc_status hfi_parse_init_done_properties(
|
||||||
__func__, data_ptr, prop_id);
|
__func__, data_ptr, prop_id);
|
||||||
break;
|
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;
|
return status;
|
||||||
|
|
Loading…
Add table
Reference in a new issue