summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkatarama Avadhani <venkatarama.avadhani@ittiam.com>2017-04-06 12:08:34 +0530
committerMSe <mse1969@posteo.de>2017-07-07 10:50:02 +0200
commit463b3d9552216295f186f4dab027c813b3242782 (patch)
treed8f7389576d3d4490a328dd0b5e9db8363960e2b
parentbf8f174e15344d89664426a4dc75187b891c0f7c (diff)
downloadandroid_external_libmpeg2-463b3d9552216295f186f4dab027c813b3242782.tar.gz
android_external_libmpeg2-463b3d9552216295f186f4dab027c813b3242782.tar.bz2
android_external_libmpeg2-463b3d9552216295f186f4dab027c813b3242782.zip
Fix Bytes Consumed Issue
Number of bytes consumed in multi-thread run was 0, causing the decoder to run in an infinite loop. Fixed the same. Bug: 34203195 Bug: 34203325 AOSP-Change-Id: I3adc833b6a6a69e63f62f2e179a1ed886f39b3ee (cherry picked from commit d4c1922a42aafe9a2511f630a8f4c05644517709) CVE-2017-0685 Change-Id: I6a008cfe36f31c8a54086cac82d5046bc6fa46f0
-rw-r--r--decoder/impeg2d_dec_hdr.c22
-rw-r--r--decoder/impeg2d_decoder.c28
2 files changed, 46 insertions, 4 deletions
diff --git a/decoder/impeg2d_dec_hdr.c b/decoder/impeg2d_dec_hdr.c
index 2c2f24b..a1b61ab 100644
--- a/decoder/impeg2d_dec_hdr.c
+++ b/decoder/impeg2d_dec_hdr.c
@@ -1724,6 +1724,15 @@ IMPEG2D_ERROR_CODES_T impeg2d_process_video_bit_stream(dec_state_t *ps_dec)
if(u4_start_code_found == 0)
{
impeg2d_next_start_code(ps_dec);
+ /* In case a dec_pic_data call has not been made, the number of
+ * bytes consumed in the previous header decode has to be
+ * consumed. Not consuming it will result in zero bytes consumed
+ * loops in case there are multiple headers and the second
+ * or a future header has a resolution change/other error where
+ * the bytes of the last header are not consumed.
+ */
+ ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+ ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
}
}
if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
@@ -1790,7 +1799,18 @@ IMPEG2D_ERROR_CODES_T impeg2d_process_video_bit_stream(dec_state_t *ps_dec)
FLUSH_BITS(ps_dec->s_bit_stream.u4_offset, ps_dec->s_bit_stream.u4_buf, ps_dec->s_bit_stream.u4_buf_nxt, 8, ps_dec->s_bit_stream.pu4_buf_aligned);
}
impeg2d_next_start_code(ps_dec);
-
+ if (0 == u4_start_code_found)
+ {
+ /* In case a dec_pic_data call has not been made, the number of
+ * bytes consumed in the previous header decode has to be
+ * consumed. Not consuming it will result in zero bytes consumed
+ * loops in case there are multiple headers and the second
+ * or a future header has a resolution change/other error where
+ * the bytes of the last header are not consumed.
+ */
+ ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+ ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
+ }
}
if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
{
diff --git a/decoder/impeg2d_decoder.c b/decoder/impeg2d_decoder.c
index e9b31a0..fa88bb5 100644
--- a/decoder/impeg2d_decoder.c
+++ b/decoder/impeg2d_decoder.c
@@ -185,6 +185,8 @@ void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
ps_dec = (dec_state_t *)pv_dec;
ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
+ ps_dec->i4_bytes_consumed = 0;
+ ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
IMPEG2D_FRM_NUM_SET();
@@ -209,7 +211,7 @@ void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
if ((IMPEG2D_ERROR_CODES_T) IVD_RES_CHANGED == e_error)
{
- ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
+ ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
ps_dec->u2_header_done = 0;
}
else if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
@@ -222,8 +224,18 @@ void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
}
else
{
- if(ps_dec->i4_num_cores > 1)
+ if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+ {
+ /* If the number of bytes consumed has been updated by
+ * get_slice_pos function, then use that. Else, the bytes consumed is
+ * calculated from the offset. The bytes consumed for multi-thread runs
+ * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+ * function has been called. If that function has not run, then we have
+ * encountered an error but still have to consume the bytes in header
+ * decode, etc.
+ */
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+ }
else
{
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
@@ -253,8 +265,18 @@ void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
/**************************************************************************/
ps_op->s_ivd_video_decode_op_t.u4_error_code = IV_SUCCESS;
- if(ps_dec->i4_num_cores > 1)
+ if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+ {
+ /* If the number of bytes consumed has been updated by
+ * get_slice_pos function, then use that. Else, the bytes consumed is
+ * calculated from the offset. The bytes consumed for multi-thread runs
+ * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+ * function has been called. If that function has not run, then we have
+ * encountered an error but still have to consume the bytes in header
+ * decode, etc.
+ */
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+ }
else
{
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;