[FFmpeg-devel] [PATCH v5 3/7] libavformat/asfdec: Fix type of value_len
James Almer
jamrial at gmail.com
Thu Sep 30 06:52:33 EEST 2021
On 9/29/2021 11:58 PM, Soft Works wrote:
> The value_len is an uint32 not an int32 per spec. That
> value must not be truncated, neither by casting to int, nor by any
> conditional checks, because at the end of get_tag, this value is
> needed to move forward in parsing. When the len value gets
> modified, the parsing may break.
>
> Signed-off-by: softworkz <softworkz at hotmail.com>
> ---
> v5: Split into pieces as requested
>
> libavformat/asfdec_f.c | 24 +++++++++++-------------
> 1 file changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
> index 076b5ab147..d017fae019 100644
> --- a/libavformat/asfdec_f.c
> +++ b/libavformat/asfdec_f.c
> @@ -218,7 +218,7 @@ static uint64_t get_value(AVIOContext *pb, int type, int type2_size)
> }
> }
>
> -static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size)
> +static void get_tag(AVFormatContext *s, const char *key, int type, uint32_t len, int type2_size)
There's an av_assert0() in this function to ensure len will never be
bigger than (INT_MAX - 22) / 2. And len is used as argument for
avio_read(), which takes an int, not an unsigned int. So this change is
not ok.
> {
> ASFContext *asf = s->priv_data;
> char *value = NULL;
> @@ -528,7 +528,7 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
> static int asf_read_content_desc(AVFormatContext *s, int64_t size)
> {
> AVIOContext *pb = s->pb;
> - int len1, len2, len3, len4, len5;
> + uint32_t len1, len2, len3, len4, len5;
>
> len1 = avio_rl16(pb);
> len2 = avio_rl16(pb);
> @@ -602,25 +602,23 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
> {
> AVIOContext *pb = s->pb;
> ASFContext *asf = s->priv_data;
> - int n, stream_num, name_len_utf16, name_len_utf8, value_len;
> + int n, name_len_utf8;
> + uint16_t stream_num, name_len_utf16, value_type;
> + uint32_t value_len;
> int ret, i;
> n = avio_rl16(pb);
>
> for (i = 0; i < n; i++) {
> uint8_t *name;
> - int value_type;
>
> avio_rl16(pb); // lang_list_index
> - stream_num = avio_rl16(pb);
> - name_len_utf16 = avio_rl16(pb);
> - value_type = avio_rl16(pb); /* value_type */
> - value_len = avio_rl32(pb);
> + stream_num = (uint16_t)avio_rl16(pb);
> + name_len_utf16 = (uint16_t)avio_rl16(pb);
> + value_type = (uint16_t)avio_rl16(pb); /* value_type */
> + value_len = avio_rl32(pb);
>
> - if (value_len < 0 || value_len > UINT16_MAX)
> - return AVERROR_INVALIDDATA;
> -
> - name_len_utf8 = 2*name_len_utf16 + 1;
> - name = av_malloc(name_len_utf8);
> + name_len_utf8 = 2 * name_len_utf16 + 1;
> + name = av_malloc(name_len_utf8);
Unrelated cosmetics.
> if (!name)
> return AVERROR(ENOMEM);
>
>
More information about the ffmpeg-devel
mailing list