1*4882a593Smuzhiyun# HG changeset patch 2*4882a593Smuzhiyun# User Petr Písař <ppisar@redhat.com> 3*4882a593Smuzhiyun# Date 1560182051 25200 4*4882a593Smuzhiyun# Mon Jun 10 08:54:11 2019 -0700 5*4882a593Smuzhiyun# Branch SDL-1.2 6*4882a593Smuzhiyun# Node ID 416136310b88cbeeff8773e573e90ac1e22b3526 7*4882a593Smuzhiyun# Parent a6e3d2f5183e1cc300ad993e10e9ce077e13bd9c 8*4882a593SmuzhiyunCVE-2019-7577: Fix a buffer overread in MS_ADPCM_decode 9*4882a593SmuzhiyunIf RIFF/WAV data chunk length is shorter then expected for an audio 10*4882a593Smuzhiyunformat defined in preceeding RIFF/WAV format headers, a buffer 11*4882a593Smuzhiyunoverread can happen. 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunThis patch fixes it by checking a MS ADPCM data to be decoded are not 14*4882a593Smuzhiyunpast the initialized buffer. 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunCVE-2019-7577 17*4882a593SmuzhiyunReproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunSigned-off-by: Petr Písař <ppisar@redhat.com> 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun# HG changeset patch 22*4882a593Smuzhiyun# User Petr Písař <ppisar@redhat.com> 23*4882a593Smuzhiyun# Date 1560182069 25200 24*4882a593Smuzhiyun# Mon Jun 10 08:54:29 2019 -0700 25*4882a593Smuzhiyun# Branch SDL-1.2 26*4882a593Smuzhiyun# Node ID faf9abbcfb5fe0d0ca23c4bf0394aa226ceccf02 27*4882a593Smuzhiyun# Parent 416136310b88cbeeff8773e573e90ac1e22b3526 28*4882a593SmuzhiyunCVE-2019-7577: Fix a buffer overread in MS_ADPCM_nibble and MS_ADPCM_decode 29*4882a593SmuzhiyunIf a chunk of RIFF/WAV file with MS ADPCM encoding contains an invalid 30*4882a593Smuzhiyunpredictor (a valid predictor's value is between 0 and 6 inclusive), 31*4882a593Smuzhiyuna buffer overread can happen when the predictor is used as an index 32*4882a593Smuzhiyuninto an array of MS ADPCM coefficients. 33*4882a593Smuzhiyun 34*4882a593SmuzhiyunThe overead happens when indexing MS_ADPCM_state.aCoeff[] array in 35*4882a593SmuzhiyunMS_ADPCM_decode() and later when dereferencing a coef pointer in 36*4882a593SmuzhiyunMS_ADPCM_nibble(). 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunThis patch fixes it by checking the MS ADPCM predictor values fit 39*4882a593Smuzhiyuninto the valid range. 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunCVE-2019-7577 42*4882a593SmuzhiyunReproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunSigned-off-by: Petr Písař <ppisar@redhat.com> 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunCVE: CVE-2019-7577 47*4882a593SmuzhiyunUpstream-Status: Backport 48*4882a593SmuzhiyunSigned-off-by: Anuj Mittal <anuj.mittal@intel.com> 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunRefresh CVE-2019-7577.patch as it can't be applyed when using PATCHTOOL = "patch". 51*4882a593SmuzhiyunSigned-off-by: Zheng Ruoqin <zhengrq.fnst@cn.fujitsu.com> 52*4882a593Smuzhiyun--- 53*4882a593Smuzhiyun src/audio/SDL_wave.c | 17 ++++++++++++++++- 54*4882a593Smuzhiyun 1 file changed, 16 insertions(+), 1 deletion(-) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyundiff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c 57*4882a593Smuzhiyunindex b4ad6c7..0bcf7e2 100644 58*4882a593Smuzhiyun--- a/src/audio/SDL_wave.c 59*4882a593Smuzhiyun+++ b/src/audio/SDL_wave.c 60*4882a593Smuzhiyun@@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state, 61*4882a593Smuzhiyun static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) 62*4882a593Smuzhiyun { 63*4882a593Smuzhiyun struct MS_ADPCM_decodestate *state[2]; 64*4882a593Smuzhiyun- Uint8 *freeable, *encoded, *decoded; 65*4882a593Smuzhiyun+ Uint8 *freeable, *encoded, *encoded_end, *decoded; 66*4882a593Smuzhiyun Sint32 encoded_len, samplesleft; 67*4882a593Smuzhiyun Sint8 nybble, stereo; 68*4882a593Smuzhiyun Sint16 *coeff[2]; 69*4882a593Smuzhiyun@@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) 70*4882a593Smuzhiyun /* Allocate the proper sized output buffer */ 71*4882a593Smuzhiyun encoded_len = *audio_len; 72*4882a593Smuzhiyun encoded = *audio_buf; 73*4882a593Smuzhiyun+ encoded_end = encoded + encoded_len; 74*4882a593Smuzhiyun freeable = *audio_buf; 75*4882a593Smuzhiyun *audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) * 76*4882a593Smuzhiyun MS_ADPCM_state.wSamplesPerBlock* 77*4882a593Smuzhiyun@@ -141,10 +142,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) 78*4882a593Smuzhiyun state[1] = &MS_ADPCM_state.state[stereo]; 79*4882a593Smuzhiyun while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) { 80*4882a593Smuzhiyun /* Grab the initial information for this block */ 81*4882a593Smuzhiyun+ if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short; 82*4882a593Smuzhiyun state[0]->hPredictor = *encoded++; 83*4882a593Smuzhiyun if ( stereo ) { 84*4882a593Smuzhiyun state[1]->hPredictor = *encoded++; 85*4882a593Smuzhiyun } 86*4882a593Smuzhiyun+ if (state[0]->hPredictor >= 7 || state[1]->hPredictor >= 7) { 87*4882a593Smuzhiyun+ goto invalid_predictor; 88*4882a593Smuzhiyun+ } 89*4882a593Smuzhiyun state[0]->iDelta = ((encoded[1]<<8)|encoded[0]); 90*4882a593Smuzhiyun encoded += sizeof(Sint16); 91*4882a593Smuzhiyun if ( stereo ) { 92*4882a593Smuzhiyun@@ -188,6 +193,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) 93*4882a593Smuzhiyun samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)* 94*4882a593Smuzhiyun MS_ADPCM_state.wavefmt.channels; 95*4882a593Smuzhiyun while ( samplesleft > 0 ) { 96*4882a593Smuzhiyun+ if (encoded + 1 > encoded_end) goto too_short; 97*4882a593Smuzhiyun+ 98*4882a593Smuzhiyun nybble = (*encoded)>>4; 99*4882a593Smuzhiyun new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]); 100*4882a593Smuzhiyun decoded[0] = new_sample&0xFF; 101*4882a593Smuzhiyun@@ -209,6 +216,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) 102*4882a593Smuzhiyun } 103*4882a593Smuzhiyun SDL_free(freeable); 104*4882a593Smuzhiyun return(0); 105*4882a593Smuzhiyun+too_short: 106*4882a593Smuzhiyun+ SDL_SetError("Too short chunk for a MS ADPCM decoder"); 107*4882a593Smuzhiyun+ SDL_free(freeable); 108*4882a593Smuzhiyun+ return(-1); 109*4882a593Smuzhiyun+invalid_predictor: 110*4882a593Smuzhiyun+ SDL_SetError("Invalid predictor value for a MS ADPCM decoder"); 111*4882a593Smuzhiyun+ SDL_free(freeable); 112*4882a593Smuzhiyun+ return(-1); 113*4882a593Smuzhiyun } 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun struct IMA_ADPCM_decodestate { 116*4882a593Smuzhiyun-- 117*4882a593Smuzhiyun2.7.4 118*4882a593Smuzhiyun 119