Fix for segmentation fault in hf generator

Number of envelopes is becoming zero because of erroneous input
stream.Inside SBR start band and stop band are calculated based
on number of envelope's.

In this case start bands is becoming negative. In sbr processing
buffer is accessed from start to stop band. This is causing OOB
read access

Bug:113037143
Test: poc
Change-Id: Iade10e8cb86676784703e7226b7e132761eb12b1
(cherry picked from commit 4e5b9cb8f6)
This commit is contained in:
Ramesh Katuri 2018-08-31 16:48:00 +05:30 committed by Ray Essick
parent 8fe5da1ed4
commit c992830e35
3 changed files with 65 additions and 40 deletions

View file

@ -238,7 +238,7 @@ VOID ixheaacd_process_del_cod_env_data(
} }
} }
static PLATFORM_INLINE VOID static PLATFORM_INLINE WORD32
ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data, ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data, ia_sbr_frame_info_data_struct *ptr_sbr_data,
ia_sbr_prev_frame_data_struct *ptr_prev_data, ia_sbr_prev_frame_data_struct *ptr_prev_data,
@ -270,6 +270,8 @@ ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
p_frame_info->border_vec[0] = start_pos_est; p_frame_info->border_vec[0] = start_pos_est;
p_frame_info->noise_border_vec[0] = start_pos_est; p_frame_info->noise_border_vec[0] = start_pos_est;
if (start_pos_est < 0) return -1;
if (ptr_sbr_data->coupling_mode != COUPLING_BAL) { if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
num_env_sf = num_env_sf =
((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]); ((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);
@ -279,6 +281,8 @@ ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp); add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
} }
} }
return 0;
} }
WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data, WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
@ -568,19 +572,22 @@ VOID ixheaacd_sbr_env_dequant_coup(
(1 + pow(2, temp_r - pan_offset[1]))); (1 + pow(2, temp_r - pan_offset[1])));
} }
} }
VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0, WORD32 ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
ia_sbr_header_data_struct *ptr_header_data_ch_1, ia_sbr_header_data_struct *ptr_header_data_ch_1,
ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0, ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1, ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
ixheaacd_misc_tables *ptr_common_tables) { ixheaacd_misc_tables *ptr_common_tables) {
FLAG error_code; FLAG error_code;
WORD32 err = 0;
WORD32 usac_flag = ptr_header_data_ch_0->usac_flag; WORD32 usac_flag = ptr_header_data_ch_0->usac_flag;
ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0, err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
ptr_prev_data_ch_0, ptr_prev_data_ch_1, ptr_prev_data_ch_0, ptr_prev_data_ch_1,
ptr_common_tables); ptr_common_tables);
if (err) return err;
ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0, ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
ptr_prev_data_ch_0); ptr_prev_data_ch_0);
@ -598,9 +605,11 @@ VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
if (ptr_sbr_data_ch_1 != NULL) { if (ptr_sbr_data_ch_1 != NULL) {
error_code = ptr_header_data_ch_0->err_flag; error_code = ptr_header_data_ch_0->err_flag;
ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1, err = ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
ptr_prev_data_ch_1, ptr_prev_data_ch_0, ptr_prev_data_ch_1, ptr_prev_data_ch_0,
ptr_common_tables); ptr_common_tables);
if (err) return err;
ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1, ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
ptr_prev_data_ch_1); ptr_prev_data_ch_1);
@ -618,9 +627,11 @@ VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
if (!usac_flag) { if (!usac_flag) {
if (!error_code && ptr_header_data_ch_0->err_flag) { if (!error_code && ptr_header_data_ch_0->err_flag) {
ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0, err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
ptr_prev_data_ch_0, ptr_prev_data_ch_1, ptr_prev_data_ch_0, ptr_prev_data_ch_1,
ptr_common_tables); ptr_common_tables);
if (err) return err;
} }
} }
@ -631,13 +642,16 @@ VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1); ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
} }
} }
return 0;
} }
VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data, WORD32 ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data, ia_sbr_frame_info_data_struct *ptr_sbr_data,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
ixheaacd_misc_tables *pstr_common_tables) { ixheaacd_misc_tables *pstr_common_tables) {
FLAG error_code; FLAG error_code;
WORD32 err;
WORD16 env_sf_local_arr[MAX_FREQ_COEFFS]; WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
WORD32 usac_flag = ptr_header_data->usac_flag; WORD32 usac_flag = ptr_header_data->usac_flag;
WORD32 temp_1 = WORD32 temp_1 =
@ -664,8 +678,12 @@ VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
if (ptr_header_data->err_flag_prev && !usac_flag) { if (ptr_header_data->err_flag_prev && !usac_flag) {
WORD16 *ptr1, *ptr2; WORD16 *ptr1, *ptr2;
WORD32 i; WORD32 i;
ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
ptr_prev_data_ch_0, pstr_common_tables); err = ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
ptr_prev_data_ch_0,
pstr_common_tables);
if (err) return err;
if (ptr_sbr_data->coupling_mode != if (ptr_sbr_data->coupling_mode !=
(WORD16)ptr_prev_data_ch_0->coupling_mode) { (WORD16)ptr_prev_data_ch_0->coupling_mode) {
@ -708,14 +726,19 @@ VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr, memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
sizeof(WORD16) * MAX_FREQ_COEFFS); sizeof(WORD16) * MAX_FREQ_COEFFS);
ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0, err = ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data,
ptr_prev_data_ch_1, pstr_common_tables); ptr_prev_data_ch_0, ptr_prev_data_ch_1,
return; pstr_common_tables);
if (err) return err;
return 0;
} }
} }
} }
if (!usac_flag) if (!usac_flag)
ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res); ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
return 0;
} }
VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag, VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,

View file

@ -20,13 +20,13 @@
#ifndef IXHEAACD_ENV_DEC_H #ifndef IXHEAACD_ENV_DEC_H
#define IXHEAACD_ENV_DEC_H #define IXHEAACD_ENV_DEC_H
VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0, WORD32 ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
ia_sbr_header_data_struct *ptr_header_data_ch_1, ia_sbr_header_data_struct *ptr_header_data_ch_1,
ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0, ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1, ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
ixheaacd_misc_tables *ptr_common_tables); ixheaacd_misc_tables *ptr_common_tables);
VOID ixheaacd_dec_sbrdata_for_pvc(ia_sbr_header_data_struct *ptr_header_data, VOID ixheaacd_dec_sbrdata_for_pvc(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data, ia_sbr_frame_info_data_struct *ptr_sbr_data,
@ -55,11 +55,11 @@ VOID ixheaacd_harm_idx_onethree(FLAG noise_absc_flag, WORD16 num_subband,
WORD16 *ptr_sine_level_buf, WORD16 noise_e, WORD16 *ptr_sine_level_buf, WORD16 noise_e,
WORD freq_inv_flag, WORD32 harm_index); WORD freq_inv_flag, WORD32 harm_index);
VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data, WORD32 ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data, ia_sbr_frame_info_data_struct *ptr_sbr_data,
ia_sbr_prev_frame_data_struct *ptr_prev_data, ia_sbr_prev_frame_data_struct *ptr_prev_data,
ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1, ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
ixheaacd_misc_tables *pstr_common_tables); ixheaacd_misc_tables *pstr_common_tables);
VOID ixheaacd_lean_sbrconcealment(ia_sbr_header_data_struct *ptr_header_data, VOID ixheaacd_lean_sbrconcealment(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data, ia_sbr_frame_info_data_struct *ptr_sbr_data,

View file

@ -566,13 +566,15 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self,
ixheaacd_dec_sbrdata_for_pvc(ptr_header_data[0], ptr_frame_data[0], ixheaacd_dec_sbrdata_for_pvc(ptr_header_data[0], ptr_frame_data[0],
pstr_sbr_channel[0]->pstr_prev_frame_data); pstr_sbr_channel[0]->pstr_prev_frame_data);
} else if (ptr_frame_data[0]->sbr_mode == ORIG_SBR) { } else if (ptr_frame_data[0]->sbr_mode == ORIG_SBR) {
ixheaacd_dec_sbrdata( err = ixheaacd_dec_sbrdata(
ptr_header_data[0], ptr_header_data[1], ptr_frame_data[0], ptr_header_data[0], ptr_header_data[1], ptr_frame_data[0],
pstr_sbr_channel[0]->pstr_prev_frame_data, pstr_sbr_channel[0]->pstr_prev_frame_data,
(stereo || dual_mono) ? ptr_frame_data[1] : NULL, (stereo || dual_mono) ? ptr_frame_data[1] : NULL,
(stereo || dual_mono) ? pstr_sbr_channel[1]->pstr_prev_frame_data (stereo || dual_mono) ? pstr_sbr_channel[1]->pstr_prev_frame_data
: NULL, : NULL,
self->pstr_common_tables); self->pstr_common_tables);
if (err) return err;
} }
if (ptr_header_data[0]->channel_mode == PS_STEREO && if (ptr_header_data[0]->channel_mode == PS_STEREO &&