From eda594771625201c51ca79d2dfec154d3c69ac1f Mon Sep 17 00:00:00 2001 From: Naveen Kumar P Date: Fri, 2 Jun 2017 16:57:28 +0530 Subject: Check number of output buffers and sizes Bug: 37435531 Bug: 36817631 Bug: 36492741 Change-Id: I85e3da9a8aaefaac0b494868fdc94d858e4cf8e6 (cherry picked from commit 1ffb19f7ae4c9622a270ad87f950ce8ffe622783) CVE-2017-0758 --- decoder/ihevcd_decode.c | 5 +++ decoder/ihevcd_utils.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) (limited to 'decoder') diff --git a/decoder/ihevcd_decode.c b/decoder/ihevcd_decode.c index d656519..87c3bd7 100644 --- a/decoder/ihevcd_decode.c +++ b/decoder/ihevcd_decode.c @@ -81,6 +81,7 @@ #define NUM_FRAMES_LIMIT 0x7FFFFFFF #endif +IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec); IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec, process_ctxt_t *ps_proc, UWORD8 *pu1_y_dst, @@ -471,6 +472,10 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ihevcd_init_proc_ctxt(ps_proc, 0); } + /* Output buffer check */ + ret = ihevcd_check_out_buf_size(ps_codec); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + /* Set remaining number of rows to be processed */ ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx], ps_dec_ip->s_out_buffer.pu1_bufs[0], diff --git a/decoder/ihevcd_utils.c b/decoder/ihevcd_utils.c index 7d76577..14cdd2b 100755 --- a/decoder/ihevcd_utils.c +++ b/decoder/ihevcd_utils.c @@ -658,6 +658,103 @@ IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec) } return ret; } +/** +******************************************************************************* +* +* @brief +* Output buffer check +* +* @par Description: +* Check for the number of buffers and buffer sizes of output buffer +* +* @param[in] ps_codec +* Pointer to codec context +* +* @returns Error from IHEVCD_ERROR_T +* +* @remarks +* +* +******************************************************************************* +*/ +IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec) +{ + ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer; + UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; + UWORD32 u4_min_num_out_bufs = 0, i; + UWORD32 wd, ht; + + if(0 == ps_codec->i4_share_disp_buf) + { + wd = ps_codec->i4_disp_wd; + ht = ps_codec->i4_disp_ht; + } + else + { + /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */ + return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; + } + + if(ps_codec->e_chroma_fmt == IV_YUV_420P) + u4_min_num_out_bufs = MIN_OUT_BUFS_420; + else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) + u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; + else if(ps_codec->e_chroma_fmt == IV_RGB_565) + u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; + else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) + u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; + else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) + || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) + u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; + + if(ps_codec->e_chroma_fmt == IV_YUV_420P) + { + au4_min_out_buf_size[0] = (wd * ht); + au4_min_out_buf_size[1] = (wd * ht) >> 2; + au4_min_out_buf_size[2] = (wd * ht) >> 2; + } + else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) + { + au4_min_out_buf_size[0] = (wd * ht) * 2; + au4_min_out_buf_size[1] = + au4_min_out_buf_size[2] = 0; + } + else if(ps_codec->e_chroma_fmt == IV_RGB_565) + { + au4_min_out_buf_size[0] = (wd * ht) * 2; + au4_min_out_buf_size[1] = + au4_min_out_buf_size[2] = 0; + } + else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) + { + au4_min_out_buf_size[0] = (wd * ht) * 4; + au4_min_out_buf_size[1] = + au4_min_out_buf_size[2] = 0; + } + else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) + || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) + { + au4_min_out_buf_size[0] = (wd * ht); + au4_min_out_buf_size[1] = (wd * ht) >> 1; + au4_min_out_buf_size[2] = 0; + } + + if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs) + { + return (IHEVCD_ERROR_T)IV_FAIL; + } + + for (i = 0 ; i < u4_min_num_out_bufs; i++) + { + if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i]) + { + return (IHEVCD_ERROR_T)IV_FAIL; + } + } + + return (IHEVCD_ERROR_T)IHEVCD_SUCCESS; +} + /** ******************************************************************************* * @@ -713,6 +810,10 @@ IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) ps_codec->s_parse.i4_first_pic_init = 1; } + /* Output buffer check */ + ret = ihevcd_check_out_buf_size(ps_codec); + RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); + /* Initialize all the slice headers' slice addresses to zero */ { WORD32 slice_idx; -- cgit v1.2.3