| # HG changeset patch |
| # User Petr Písař <ppisar@redhat.com> |
| # Date 1560181859 25200 |
| # Mon Jun 10 08:50:59 2019 -0700 |
| # Branch SDL-1.2 |
| # Node ID a6e3d2f5183e1cc300ad993e10e9ce077e13bd9c |
| # Parent 388987dff7bf8f1e214e69c2e4f1aa31e06396b5 |
| CVE-2019-7574: Fix a buffer overread in IMA_ADPCM_decode |
| If data chunk was shorter than expected based on a WAV format |
| definition, IMA_ADPCM_decode() tried to read past the data chunk |
| buffer. This patch fixes it. |
| |
| CVE-2019-7574 |
| https://bugzilla.libsdl.org/show_bug.cgi?id=4496 |
| |
| Signed-off-by: Petr Písař <ppisar@redhat.com> |
| |
| CVE: CVE-2019-7574 |
| Upstream-Status: Backport |
| Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| |
| diff -r 388987dff7bf -r a6e3d2f5183e src/audio/SDL_wave.c |
| --- a/src/audio/SDL_wave.c Sat Jun 08 18:02:09 2019 -0700 |
| +++ b/src/audio/SDL_wave.c Mon Jun 10 08:50:59 2019 -0700 |
| @@ -331,7 +331,7 @@ |
| static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| { |
| struct IMA_ADPCM_decodestate *state; |
| - Uint8 *freeable, *encoded, *decoded; |
| + Uint8 *freeable, *encoded, *encoded_end, *decoded; |
| Sint32 encoded_len, samplesleft; |
| unsigned int c, channels; |
| |
| @@ -347,6 +347,7 @@ |
| /* 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/IMA_ADPCM_state.wavefmt.blockalign) * |
| IMA_ADPCM_state.wSamplesPerBlock* |
| @@ -362,6 +363,7 @@ |
| while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) { |
| /* Grab the initial information for this block */ |
| for ( c=0; c<channels; ++c ) { |
| + if (encoded + 4 > encoded_end) goto invalid_size; |
| /* Fill the state information for this block */ |
| state[c].sample = ((encoded[1]<<8)|encoded[0]); |
| encoded += 2; |
| @@ -384,6 +386,7 @@ |
| samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels; |
| while ( samplesleft > 0 ) { |
| for ( c=0; c<channels; ++c ) { |
| + if (encoded + 4 > encoded_end) goto invalid_size; |
| Fill_IMA_ADPCM_block(decoded, encoded, |
| c, channels, &state[c]); |
| encoded += 4; |
| @@ -395,6 +398,10 @@ |
| } |
| SDL_free(freeable); |
| return(0); |
| +invalid_size: |
| + SDL_SetError("Unexpected chunk length for an IMA ADPCM decoder"); |
| + SDL_free(freeable); |
| + return(-1); |
| } |
| |
| SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc, |