From f89288f35a782206e44b3fb2ef39d2593321c556 Mon Sep 17 00:00:00 2001 From: "jiyong.min" Date: Wed, 26 Jun 2019 16:46:00 +0900 Subject: [PATCH] Apply patch from MCD [Problem] unallocated pointer is getting freed [Cause] unallocated pointer is getting freed [Solution] Merged changes from FFMPEG, In ff_init_vlc_sparse() function of libav\libavcodec\bitstream.c file, which will not free unallocated pointer Change-Id: Ie479987e7bcbfe362b6c0d454cff92de6b4d9a25 --- libavcodec/bitstream.c | 62 +++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 656ac47..640af7e 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -264,7 +264,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, 'use_static' should be set to 1 for tables, which should be freed with av_free_static(), 0 if ff_free_vlc() will be used. */ -int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, +int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, @@ -272,25 +272,26 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, { VLCcode *buf; int i, j, ret; + VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34 + VLC localvlc, *vlc; + vlc = vlc_arg; vlc->bits = nb_bits; if (flags & INIT_VLC_USE_NEW_STATIC) { - if (vlc->table_size && vlc->table_size == vlc->table_allocated) { - return 0; - } else if (vlc->table_size) { - return AVERROR_BUG; - } + assert(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf)); + buf = localbuf; + localvlc = *vlc_arg; + vlc = &localvlc; + vlc->table_size = 0; } else { vlc->table = NULL; vlc->table_allocated = 0; vlc->table_size = 0; - } - ff_dlog(NULL, "build table nb_codes=%d\n", nb_codes); - - buf = av_malloc((nb_codes + 1) * sizeof(VLCcode)); - if (!buf) - return AVERROR(ENOMEM); + buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode)); + if (!buf) + return AVERROR(ENOMEM); + } assert(symbols_size <= 2 || !symbols); j = 0; @@ -299,15 +300,27 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \ if (!(condition)) \ continue; \ + if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \ + av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\ + if (!(flags & INIT_VLC_USE_NEW_STATIC)) \ + av_free(buf); \ + return -1; \ + } \ GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \ + if (buf[j].code >= (1LL< nb_bits); @@ -318,19 +331,22 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, ret = build_table(vlc, nb_bits, nb_codes, buf, flags); - av_free(buf); - if (ret < 0) { - av_freep(&vlc->table); - return ret; + if (flags & INIT_VLC_USE_NEW_STATIC) { + if(vlc->table_size != vlc->table_allocated) + av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); + + assert(ret >= 0); + *vlc_arg = *vlc; + } else { + av_free(buf); + if (ret < 0) { + av_freep(&vlc->table); + return ret; + } } - if ((flags & INIT_VLC_USE_NEW_STATIC) && - vlc->table_size != vlc->table_allocated) - av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", - vlc->table_size, vlc->table_allocated); return 0; } - void ff_free_vlc(VLC *vlc) { av_freep(&vlc->table); -- 2.7.4