Decoder: Fix Null dereference

Add checks to validate long term index and
max long term index parsed in MMCO commands.

Bug: 140358770
Bug: 140680655
Bug: 148772548
Bug: 152148135
Bug: 152434373
Bug: 152550528

Test: poc in bug
Change-Id: I9052ce7721491fdd5fb4807ec33e399cee8c70cf
This commit is contained in:
Aasaipriya Chandran 2020-06-10 13:42:04 +05:30 committed by Hamsalekha S
parent fa8ec83555
commit 083b9fc086
3 changed files with 36 additions and 9 deletions

View file

@ -50,6 +50,7 @@
#define RESET_NONREF_PICTURES 7 #define RESET_NONREF_PICTURES 7
#define RESET_ALL_PICTURES 8 #define RESET_ALL_PICTURES 8
#define NO_LONG_TERM_INDICIES 255
struct field_t struct field_t
{ {
/* picNum of tbe reference field */ /* picNum of tbe reference field */
@ -93,7 +94,7 @@ typedef struct
struct dpb_info_t as_dpb_info[MAX_REF_BUFS]; /** Physical storage for dpbInfo for ref bufs */ struct dpb_info_t as_dpb_info[MAX_REF_BUFS]; /** Physical storage for dpbInfo for ref bufs */
UWORD8 u1_num_st_ref_bufs; /** Number of short term ref. buffers */ UWORD8 u1_num_st_ref_bufs; /** Number of short term ref. buffers */
UWORD8 u1_num_lt_ref_bufs; /** Number of long term ref. buffer */ UWORD8 u1_num_lt_ref_bufs; /** Number of long term ref. buffer */
UWORD8 u1_max_lt_pic_idx_plus1; /** Maximum long term pictures - 0 to max_long_term_pic_idx */ UWORD8 u1_max_lt_frame_idx; /** Maximum long term frame index */
UWORD8 u1_num_gaps; /** Total number of outstanding gaps */ UWORD8 u1_num_gaps; /** Total number of outstanding gaps */
void * pv_codec_handle; /* For Error Handling */ void * pv_codec_handle; /* For Error Handling */
WORD32 i4_max_frm_num; /** Max frame number */ WORD32 i4_max_frm_num; /** Max frame number */

View file

@ -851,6 +851,8 @@ WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx)
*/ */
WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
{ {
dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
dec_seq_params_t *ps_sps = ps_pps->ps_sps;
dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch); dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch);
dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
@ -890,7 +892,7 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
{ {
UWORD32 u4_mmco; UWORD32 u4_mmco;
UWORD32 u4_diff_pic_num; UWORD32 u4_diff_pic_num;
UWORD32 u4_lt_idx, u4_max_lt_idx; UWORD32 u4_lt_idx, u4_max_lt_idx_plus1;
u4_mmco = ih264d_uev(pu4_bitstrm_ofst, u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
pu4_bitstrm_buf); pu4_bitstrm_buf);
@ -933,9 +935,14 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
case SET_MAX_LT_INDEX: case SET_MAX_LT_INDEX:
{ {
u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst, u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst,
pu4_bitstrm_buf); pu4_bitstrm_buf);
ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx; if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames)
{
/* Invalid max LT ref index */
return -1;
}
ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1;
break; break;
} }
case RESET_REF_PICTURES: case RESET_REF_PICTURES:
@ -959,7 +966,6 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
j++; j++;
} }
ps_dpb_cmds->u1_num_of_commands = j; ps_dpb_cmds->u1_num_of_commands = j;
} }
} }
ps_dpb_cmds->u1_dpb_commands_read = 1; ps_dpb_cmds->u1_dpb_commands_read = 1;
@ -1243,6 +1249,13 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
} }
u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
(u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
{
return ERROR_DBP_MANAGER_T;
}
if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
{ {
ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
@ -1257,7 +1270,7 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
{ {
UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs; UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1 u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
if(u4_lt_idx < ps_dpb_mgr->u1_max_lt_pic_idx_plus1 if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx
&& uc_numLT > 0) && uc_numLT > 0)
{ {
struct dpb_info_t *ps_nxtDPB; struct dpb_info_t *ps_nxtDPB;
@ -1302,13 +1315,25 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds,
ps_nxtDPB->ps_prev_long = NULL; ps_nxtDPB->ps_prev_long = NULL;
} }
} }
ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx; if(u4_lt_idx == 0)
{
ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
}
else
{
ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
}
break; break;
} }
case SET_LT_INDEX: case SET_LT_INDEX:
{ {
u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
(u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
{
return ERROR_DBP_MANAGER_T;
}
ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
u4_cur_pic_num); u4_cur_pic_num);
if(ret != OK) if(ret != OK)

View file

@ -509,6 +509,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec)
ps_dec->ps_cur_pic, ps_dec->ps_cur_pic,
ps_dec->u1_pic_buf_id, ps_dec->u1_pic_buf_id,
ps_cur_slice->u2_frame_num); ps_cur_slice->u2_frame_num);
ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
} }
else else
{ {
@ -527,7 +528,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec)
ps_cur_slice->u2_frame_num, 0, ps_cur_slice->u2_frame_num, 0,
ps_cur_slice->u1_field_pic_flag); ps_cur_slice->u1_field_pic_flag);
ps_dec->ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = 1; ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = 0;
} }
} }
} }