Brad Bishop | 26bdd44 | 2019-08-16 17:08:17 -0400 | [diff] [blame] | 1 | # HG changeset patch |
| 2 | # User Petr Písař <ppisar@redhat.com> |
| 3 | # Date 1560181859 25200 |
| 4 | # Mon Jun 10 08:50:59 2019 -0700 |
| 5 | # Branch SDL-1.2 |
| 6 | # Node ID a6e3d2f5183e1cc300ad993e10e9ce077e13bd9c |
| 7 | # Parent 388987dff7bf8f1e214e69c2e4f1aa31e06396b5 |
| 8 | CVE-2019-7574: Fix a buffer overread in IMA_ADPCM_decode |
| 9 | If data chunk was shorter than expected based on a WAV format |
| 10 | definition, IMA_ADPCM_decode() tried to read past the data chunk |
| 11 | buffer. This patch fixes it. |
| 12 | |
| 13 | CVE-2019-7574 |
| 14 | https://bugzilla.libsdl.org/show_bug.cgi?id=4496 |
| 15 | |
| 16 | Signed-off-by: Petr Písař <ppisar@redhat.com> |
| 17 | |
| 18 | CVE: CVE-2019-7574 |
| 19 | Upstream-Status: Backport |
| 20 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| 21 | |
| 22 | diff -r 388987dff7bf -r a6e3d2f5183e src/audio/SDL_wave.c |
| 23 | --- a/src/audio/SDL_wave.c Sat Jun 08 18:02:09 2019 -0700 |
| 24 | +++ b/src/audio/SDL_wave.c Mon Jun 10 08:50:59 2019 -0700 |
| 25 | @@ -331,7 +331,7 @@ |
| 26 | static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| 27 | { |
| 28 | struct IMA_ADPCM_decodestate *state; |
| 29 | - Uint8 *freeable, *encoded, *decoded; |
| 30 | + Uint8 *freeable, *encoded, *encoded_end, *decoded; |
| 31 | Sint32 encoded_len, samplesleft; |
| 32 | unsigned int c, channels; |
| 33 | |
| 34 | @@ -347,6 +347,7 @@ |
| 35 | /* Allocate the proper sized output buffer */ |
| 36 | encoded_len = *audio_len; |
| 37 | encoded = *audio_buf; |
| 38 | + encoded_end = encoded + encoded_len; |
| 39 | freeable = *audio_buf; |
| 40 | *audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) * |
| 41 | IMA_ADPCM_state.wSamplesPerBlock* |
| 42 | @@ -362,6 +363,7 @@ |
| 43 | while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) { |
| 44 | /* Grab the initial information for this block */ |
| 45 | for ( c=0; c<channels; ++c ) { |
| 46 | + if (encoded + 4 > encoded_end) goto invalid_size; |
| 47 | /* Fill the state information for this block */ |
| 48 | state[c].sample = ((encoded[1]<<8)|encoded[0]); |
| 49 | encoded += 2; |
| 50 | @@ -384,6 +386,7 @@ |
| 51 | samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels; |
| 52 | while ( samplesleft > 0 ) { |
| 53 | for ( c=0; c<channels; ++c ) { |
| 54 | + if (encoded + 4 > encoded_end) goto invalid_size; |
| 55 | Fill_IMA_ADPCM_block(decoded, encoded, |
| 56 | c, channels, &state[c]); |
| 57 | encoded += 4; |
| 58 | @@ -395,6 +398,10 @@ |
| 59 | } |
| 60 | SDL_free(freeable); |
| 61 | return(0); |
| 62 | +invalid_size: |
| 63 | + SDL_SetError("Unexpected chunk length for an IMA ADPCM decoder"); |
| 64 | + SDL_free(freeable); |
| 65 | + return(-1); |
| 66 | } |
| 67 | |
| 68 | SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc, |