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