media: venus: hfi: add checks to handle capabilities from firmware

commit 8d0b89398b upstream.

The hfi parser, parses the capabilities received from venus firmware and
copies them to core capabilities. Consider below api, for example,
fill_caps - In this api, caps in core structure gets updated with the
number of capabilities received in firmware data payload. If the same api
is called multiple times, there is a possibility of copying beyond the max
allocated size in core caps.
Similar possibilities in fill_raw_fmts and fill_profile_level functions.

Cc: stable@vger.kernel.org
Fixes: 1a73374a04 ("media: venus: hfi_parser: add common capability parser")
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Signed-off-by: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Vikash Garodia 2023-08-10 07:55:03 +05:30 committed by Greg Kroah-Hartman
parent c5223e87a4
commit f784a9a899
1 changed files with 12 additions and 0 deletions

View File

@ -89,6 +89,9 @@ static void fill_profile_level(struct venus_caps *cap, const void *data,
{
const struct hfi_profile_level *pl = data;
if (cap->num_pl + num >= HFI_MAX_PROFILE_COUNT)
return;
memcpy(&cap->pl[cap->num_pl], pl, num * sizeof(*pl));
cap->num_pl += num;
}
@ -114,6 +117,9 @@ fill_caps(struct venus_caps *cap, const void *data, unsigned int num)
{
const struct hfi_capability *caps = data;
if (cap->num_caps + num >= MAX_CAP_ENTRIES)
return;
memcpy(&cap->caps[cap->num_caps], caps, num * sizeof(*caps));
cap->num_caps += num;
}
@ -140,6 +146,9 @@ static void fill_raw_fmts(struct venus_caps *cap, const void *fmts,
{
const struct raw_formats *formats = fmts;
if (cap->num_fmts + num_fmts >= MAX_FMT_ENTRIES)
return;
memcpy(&cap->fmts[cap->num_fmts], formats, num_fmts * sizeof(*formats));
cap->num_fmts += num_fmts;
}
@ -162,6 +171,9 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
rawfmts[i].buftype = fmt->buffer_type;
i++;
if (i >= MAX_FMT_ENTRIES)
return;
if (pinfo->num_planes > MAX_PLANES)
break;