diff options
Diffstat (limited to 'meta-multimedia/recipes-multimedia/gstreamer/gst-ffmpeg-0.10.13/0001-vp3-fix-oob-read-for-negative-tokens-and-memleaks-on.patch')
-rw-r--r-- | meta-multimedia/recipes-multimedia/gstreamer/gst-ffmpeg-0.10.13/0001-vp3-fix-oob-read-for-negative-tokens-and-memleaks-on.patch | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/meta-multimedia/recipes-multimedia/gstreamer/gst-ffmpeg-0.10.13/0001-vp3-fix-oob-read-for-negative-tokens-and-memleaks-on.patch b/meta-multimedia/recipes-multimedia/gstreamer/gst-ffmpeg-0.10.13/0001-vp3-fix-oob-read-for-negative-tokens-and-memleaks-on.patch new file mode 100644 index 0000000000..e83d8f402b --- /dev/null +++ b/meta-multimedia/recipes-multimedia/gstreamer/gst-ffmpeg-0.10.13/0001-vp3-fix-oob-read-for-negative-tokens-and-memleaks-on.patch @@ -0,0 +1,183 @@ +gst-ffmpeg: vp3: fix oob read for negative tokens and memleaks on error. + +Upstream-Status: Backport + +Signed-off-by: Yue.Tao <yue.tao@windriver.com> + +--- + libavcodec/vp3.c | 59 +++++++++++++++++++++++++++++++++++++++++------------ + 1 files changed, 45 insertions(+), 14 deletions(-) + +diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c +index 36715bb..ce14e63 100644 +--- a/gst-libs/ext/libav/libavcodec/vp3.c ++++ b/gst-libs/ext/libav/libavcodec/vp3.c +@@ -45,6 +45,7 @@ + #define FRAGMENT_PIXELS 8 + + static av_cold int vp3_decode_end(AVCodecContext *avctx); ++static void vp3_decode_flush(AVCodecContext *avctx); + + //FIXME split things out into their own arrays + typedef struct Vp3Fragment { +@@ -890,7 +891,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, + /* decode a VLC into a token */ + token = get_vlc2(gb, vlc_table, 11, 3); + /* use the token to get a zero run, a coefficient, and an eob run */ +- if (token <= 6) { ++ if ((unsigned) token <= 6U) { + eob_run = eob_run_base[token]; + if (eob_run_get_bits[token]) + eob_run += get_bits(gb, eob_run_get_bits[token]); +@@ -908,7 +909,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, + coeff_i += eob_run; + eob_run = 0; + } +- } else { ++ } else if (token >= 0) { + bits_to_get = coeff_get_bits[token]; + if (bits_to_get) + bits_to_get = get_bits(gb, bits_to_get); +@@ -942,6 +943,10 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, + for (i = coeff_index+1; i <= coeff_index+zero_run; i++) + s->num_coded_frags[plane][i]--; + coeff_i++; ++ } else { ++ av_log(s->avctx, AV_LOG_ERROR, ++ "Invalid token %d\n", token); ++ return -1; + } + } + +@@ -991,6 +996,8 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) + /* unpack the Y plane DC coefficients */ + residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, + 0, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + + /* reverse prediction of the Y-plane DC coefficients */ + reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]); +@@ -998,8 +1005,12 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) + /* unpack the C plane DC coefficients */ + residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, + 1, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, + 2, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + + /* reverse prediction of the C-plane DC coefficients */ + if (!(s->avctx->flags & CODEC_FLAG_GRAY)) +@@ -1036,11 +1047,17 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) + for (i = 1; i <= 63; i++) { + residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i, + 0, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + + residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, + 1, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, + 2, residual_eob_run); ++ if (residual_eob_run < 0) ++ return residual_eob_run; + } + + return 0; +@@ -1777,10 +1794,15 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * + Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data; + int qps_changed = 0, i, err; + ++#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) ++ + if (!s1->current_frame.data[0] + ||s->width != s1->width +- ||s->height!= s1->height) ++ ||s->height!= s1->height) { ++ if (s != s1) ++ copy_fields(s, s1, golden_frame, current_frame); + return -1; ++ } + + if (s != s1) { + // init tables if the first frame hasn't been decoded +@@ -1796,8 +1818,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * + memcpy(s->motion_val[1], s1->motion_val[1], c_fragment_count * sizeof(*s->motion_val[1])); + } + +-#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) +- + // copy previous frame data + copy_fields(s, s1, golden_frame, dsp); + +@@ -1987,9 +2007,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) + Vp3DecodeContext *s = avctx->priv_data; + int i; + +- if (avctx->is_copy && !s->current_frame.data[0]) +- return 0; +- + av_free(s->superblock_coding); + av_free(s->all_fragments); + av_free(s->coded_fragment_list[0]); +@@ -2016,12 +2033,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) + free_vlc(&s->motion_vector_vlc); + + /* release all frames */ +- if (s->golden_frame.data[0]) +- ff_thread_release_buffer(avctx, &s->golden_frame); +- if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) +- ff_thread_release_buffer(avctx, &s->last_frame); +- /* no need to release the current_frame since it will always be pointing +- * to the same frame as either the golden or last frame */ ++ vp3_decode_flush(avctx); + + return 0; + } +@@ -2341,6 +2353,23 @@ static void vp3_decode_flush(AVCodecContext *avctx) + ff_thread_release_buffer(avctx, &s->current_frame); + } + ++static int vp3_init_thread_copy(AVCodecContext *avctx) ++{ ++ Vp3DecodeContext *s = avctx->priv_data; ++ ++ s->superblock_coding = NULL; ++ s->all_fragments = NULL; ++ s->coded_fragment_list[0] = NULL; ++ s->dct_tokens_base = NULL; ++ s->superblock_fragments = NULL; ++ s->macroblock_coding = NULL; ++ s->motion_val[0] = NULL; ++ s->motion_val[1] = NULL; ++ s->edge_emu_buffer = NULL; ++ ++ return 0; ++} ++ + AVCodec ff_theora_decoder = { + .name = "theora", + .type = AVMEDIA_TYPE_VIDEO, +@@ -2352,6 +2381,7 @@ AVCodec ff_theora_decoder = { + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, + .flush = vp3_decode_flush, + .long_name = NULL_IF_CONFIG_SMALL("Theora"), ++ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), + .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) + }; + #endif +@@ -2367,5 +2397,6 @@ AVCodec ff_vp3_decoder = { + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, + .flush = vp3_decode_flush, + .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), ++ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), + .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) + }; +-- +1.7.5.4 + |