Fixes an integer overflow caused by uninitialized values in LTP scaling

This commit is contained in:
Koen Vos 2011-09-21 14:50:17 -04:00 committed by Jean-Marc Valin
parent 363924ee7f
commit cc34050455
5 changed files with 26 additions and 23 deletions

View file

@ -25,13 +25,13 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/ ***********************************************************************/
#ifndef _SIGPROCFIX_API_DEBUG_H_ #ifndef _MACRO_DEBUG_H_
#define _SIGPROCFIX_API_DEBUG_H_ #define _MACRO_DEBUG_H_
/* Redefine macro functions with extensive assertion in Win32_DEBUG mode. /* Redefine macro functions with extensive assertion in DEBUG mode.
As function can't be undefined, this file can't work with SigProcFIX_MacroCount.h */ As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */
#if 0 && defined (_WIN32) && defined (_DEBUG) && !defined (silk_MACRO_COUNT) #if 0 && defined (_DEBUG) && !defined (silk_MACRO_COUNT)
#undef silk_ADD16 #undef silk_ADD16
static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){ static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){
@ -161,7 +161,7 @@ static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
#undef silk_MUL #undef silk_MUL
static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){ static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){
opus_int32 ret; opus_int32 ret;
opus_int64 ret64; /* Will easily show how many bits that are needed */ opus_int64 ret64;
ret = a32 * b32; ret = a32 * b32;
ret64 = (opus_int64)a32 * (opus_int64)b32; ret64 = (opus_int64)a32 * (opus_int64)b32;
silk_assert((opus_int64)ret == ret64 ); /* Check output overflow */ silk_assert((opus_int64)ret == ret64 ); /* Check output overflow */
@ -291,7 +291,7 @@ static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32
return ret; return ret;
} }
/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
#undef silk_MLA_ovflw #undef silk_MLA_ovflw
#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) #define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32)))
#undef silk_SMLABB_ovflw #undef silk_SMLABB_ovflw
@ -549,4 +549,4 @@ static inline opus_int32 silk_CHECK_FIT32( opus_int64 a ){
*/ */
#endif #endif
#endif #endif /* _MACRO_DEBUG_H_ */

View file

@ -41,7 +41,8 @@ static inline void silk_nsq_scale_states(
opus_int subfr, /* I subframe number */ opus_int subfr, /* I subframe number */
const opus_int LTP_scale_Q14, /* I */ const opus_int LTP_scale_Q14, /* I */
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
const opus_int pitchL[ MAX_NB_SUBFR ] /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
const opus_int signal_type /* I Signal type */
); );
static inline void silk_noise_shape_quantizer( static inline void silk_noise_shape_quantizer(
@ -141,7 +142,7 @@ void silk_NSQ(
} }
} }
silk_nsq_scale_states( psEncC, NSQ, x, x_sc_Q10, sLTP, sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, pitchL ); silk_nsq_scale_states( psEncC, NSQ, x, x_sc_Q10, sLTP, sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16, A_Q12, B_Q14, silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16, A_Q12, B_Q14,
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
@ -162,7 +163,6 @@ void silk_NSQ(
#ifdef SAVE_ALL_INTERNAL_DATA #ifdef SAVE_ALL_INTERNAL_DATA
DEBUG_STORE_DATA( xq.dat, &pxq[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int16 ) ); DEBUG_STORE_DATA( xq.dat, &pxq[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int16 ) );
DEBUG_STORE_DATA( q.dat, &pulses[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int8 ) ); DEBUG_STORE_DATA( q.dat, &pulses[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int8 ) );
DEBUG_STORE_DATA( sLTP_Q16.dat, &sLTP_Q16[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int32 ) );
#endif #endif
} }
@ -370,7 +370,8 @@ static inline void silk_nsq_scale_states(
opus_int subfr, /* I subframe number */ opus_int subfr, /* I subframe number */
const opus_int LTP_scale_Q14, /* I */ const opus_int LTP_scale_Q14, /* I */
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
const opus_int pitchL[ MAX_NB_SUBFR ] /* I */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
const opus_int signal_type /* I Signal type */
) )
{ {
opus_int i, lag; opus_int i, lag;
@ -403,7 +404,7 @@ static inline void silk_nsq_scale_states(
} }
/* Scale long-term prediction state */ /* Scale long-term prediction state */
if( NSQ->rewhite_flag == 0 ) { if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
} }

View file

@ -67,7 +67,9 @@ static inline void silk_nsq_del_dec_scale_states(
opus_int smpl_buf_idx, /* I Index to newest samples in buffers */ opus_int smpl_buf_idx, /* I Index to newest samples in buffers */
const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int LTP_scale_Q14, /* I LTP state scaling */
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
const opus_int pitchL[ MAX_NB_SUBFR ] /* I Pitch lag */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
const opus_int signal_type, /* I Signal type */
const opus_int decisionDelay /* I Decision delay */
); );
/******************************************/ /******************************************/
@ -241,7 +243,7 @@ void silk_NSQ_del_dec(
} }
silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x, x_sc_Q10, sLTP, sLTP_Q16, k, silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x, x_sc_Q10, sLTP, sLTP_Q16, k,
psEncC->nStatesDelayedDecision, smpl_buf_idx, LTP_scale_Q14, Gains_Q16, pitchL ); psEncC->nStatesDelayedDecision, smpl_buf_idx, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16, silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q16,
delayedGain_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], delayedGain_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
@ -273,7 +275,6 @@ void silk_NSQ_del_dec(
pxq[ i - decisionDelay ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND( pxq[ i - decisionDelay ] = ( opus_int16 )silk_SAT16( silk_RSHIFT_ROUND(
silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ psEncC->nb_subfr - 1 ] ), 10 ) ); silk_SMULWW( psDD->Xq_Q10[ last_smple_idx ], Gains_Q16[ psEncC->nb_subfr - 1 ] ), 10 ) );
NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ]; NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay + i ] = psDD->Pred_Q16[ last_smple_idx ];
} }
silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
@ -289,7 +290,6 @@ void silk_NSQ_del_dec(
#ifdef SAVE_ALL_INTERNAL_DATA #ifdef SAVE_ALL_INTERNAL_DATA
DEBUG_STORE_DATA( xq.dat, &pxq[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int16 ) ); DEBUG_STORE_DATA( xq.dat, &pxq[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int16 ) );
DEBUG_STORE_DATA( q.dat, &pulses[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int8 ) ); DEBUG_STORE_DATA( q.dat, &pulses[ -psEncC->frame_length ], psEncC->frame_length * sizeof( opus_int8 ) );
DEBUG_STORE_DATA( sLTP_Q16.dat, &sLTP_Q16[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int32 ) );
#endif #endif
} }
@ -613,7 +613,9 @@ static inline void silk_nsq_del_dec_scale_states(
opus_int smpl_buf_idx, /* I Index to newest samples in buffers */ opus_int smpl_buf_idx, /* I Index to newest samples in buffers */
const opus_int LTP_scale_Q14, /* I LTP state scaling */ const opus_int LTP_scale_Q14, /* I LTP state scaling */
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
const opus_int pitchL[ MAX_NB_SUBFR ] /* I Pitch lag */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
const opus_int signal_type, /* I Signal type */
const opus_int decisionDelay /* I Decision delay */
) )
{ {
opus_int i, k, lag; opus_int i, k, lag;
@ -647,8 +649,8 @@ static inline void silk_nsq_del_dec_scale_states(
} }
/* Scale long-term prediction state */ /* Scale long-term prediction state */
if( NSQ->rewhite_flag == 0 ) { if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); sLTP_Q16[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
} }
} }

View file

@ -446,7 +446,7 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
(just standard two's complement implementation-specific behaviour) */ (just standard two's complement implementation-specific behaviour) */
#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) #define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))
/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/ /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/
#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) #define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32))
#ifndef silk_SMLABB_ovflw #ifndef silk_SMLABB_ovflw
# define silk_SMLABB_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32))) # define silk_SMLABB_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)))