| # HG changeset patch |
| # User Petr Písař <ppisar@redhat.com> |
| # Date 1560182051 25200 |
| # Mon Jun 10 08:54:11 2019 -0700 |
| # Branch SDL-1.2 |
| # Node ID 416136310b88cbeeff8773e573e90ac1e22b3526 |
| # Parent a6e3d2f5183e1cc300ad993e10e9ce077e13bd9c |
| CVE-2019-7577: Fix a buffer overread in MS_ADPCM_decode |
| If RIFF/WAV data chunk length is shorter then expected for an audio |
| format defined in preceeding RIFF/WAV format headers, a buffer |
| overread can happen. |
| |
| This patch fixes it by checking a MS ADPCM data to be decoded are not |
| past the initialized buffer. |
| |
| CVE-2019-7577 |
| Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492 |
| |
| Signed-off-by: Petr Písař <ppisar@redhat.com> |
| |
| # HG changeset patch |
| # User Petr Písař <ppisar@redhat.com> |
| # Date 1560182069 25200 |
| # Mon Jun 10 08:54:29 2019 -0700 |
| # Branch SDL-1.2 |
| # Node ID faf9abbcfb5fe0d0ca23c4bf0394aa226ceccf02 |
| # Parent 416136310b88cbeeff8773e573e90ac1e22b3526 |
| CVE-2019-7577: Fix a buffer overread in MS_ADPCM_nibble and MS_ADPCM_decode |
| If a chunk of RIFF/WAV file with MS ADPCM encoding contains an invalid |
| predictor (a valid predictor's value is between 0 and 6 inclusive), |
| a buffer overread can happen when the predictor is used as an index |
| into an array of MS ADPCM coefficients. |
| |
| The overead happens when indexing MS_ADPCM_state.aCoeff[] array in |
| MS_ADPCM_decode() and later when dereferencing a coef pointer in |
| MS_ADPCM_nibble(). |
| |
| This patch fixes it by checking the MS ADPCM predictor values fit |
| into the valid range. |
| |
| CVE-2019-7577 |
| Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492 |
| |
| Signed-off-by: Petr Písař <ppisar@redhat.com> |
| |
| CVE: CVE-2019-7577 |
| Upstream-Status: Backport |
| Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| |
| Refresh CVE-2019-7577.patch as it can't be applyed when using PATCHTOOL = "patch". |
| Signed-off-by: Zheng Ruoqin <zhengrq.fnst@cn.fujitsu.com> |
| --- |
| src/audio/SDL_wave.c | 17 ++++++++++++++++- |
| 1 file changed, 16 insertions(+), 1 deletion(-) |
| |
| diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c |
| index b4ad6c7..0bcf7e2 100644 |
| --- a/src/audio/SDL_wave.c |
| +++ b/src/audio/SDL_wave.c |
| @@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state, |
| static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| { |
| struct MS_ADPCM_decodestate *state[2]; |
| - Uint8 *freeable, *encoded, *decoded; |
| + Uint8 *freeable, *encoded, *encoded_end, *decoded; |
| Sint32 encoded_len, samplesleft; |
| Sint8 nybble, stereo; |
| Sint16 *coeff[2]; |
| @@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| /* Allocate the proper sized output buffer */ |
| encoded_len = *audio_len; |
| encoded = *audio_buf; |
| + encoded_end = encoded + encoded_len; |
| freeable = *audio_buf; |
| *audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) * |
| MS_ADPCM_state.wSamplesPerBlock* |
| @@ -141,10 +142,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| state[1] = &MS_ADPCM_state.state[stereo]; |
| while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) { |
| /* Grab the initial information for this block */ |
| + if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short; |
| state[0]->hPredictor = *encoded++; |
| if ( stereo ) { |
| state[1]->hPredictor = *encoded++; |
| } |
| + if (state[0]->hPredictor >= 7 || state[1]->hPredictor >= 7) { |
| + goto invalid_predictor; |
| + } |
| state[0]->iDelta = ((encoded[1]<<8)|encoded[0]); |
| encoded += sizeof(Sint16); |
| if ( stereo ) { |
| @@ -188,6 +193,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)* |
| MS_ADPCM_state.wavefmt.channels; |
| while ( samplesleft > 0 ) { |
| + if (encoded + 1 > encoded_end) goto too_short; |
| + |
| nybble = (*encoded)>>4; |
| new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]); |
| decoded[0] = new_sample&0xFF; |
| @@ -209,6 +216,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| } |
| SDL_free(freeable); |
| return(0); |
| +too_short: |
| + SDL_SetError("Too short chunk for a MS ADPCM decoder"); |
| + SDL_free(freeable); |
| + return(-1); |
| +invalid_predictor: |
| + SDL_SetError("Invalid predictor value for a MS ADPCM decoder"); |
| + SDL_free(freeable); |
| + return(-1); |
| } |
| |
| struct IMA_ADPCM_decodestate { |
| -- |
| 2.7.4 |
| |