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 1560182231 25200 |
| 4 | # Mon Jun 10 08:57:11 2019 -0700 |
| 5 | # Branch SDL-1.2 |
| 6 | # Node ID a8afedbcaea0e84921dc770195c4699bda3ccdc5 |
| 7 | # Parent faf9abbcfb5fe0d0ca23c4bf0394aa226ceccf02 |
| 8 | CVE-2019-7572: Fix a buffer overwrite in IMA_ADPCM_decode |
| 9 | If data chunk was longer than expected based on a WAV format |
| 10 | definition, IMA_ADPCM_decode() tried to write past the output |
| 11 | buffer. This patch fixes it. |
| 12 | |
| 13 | Based on patch from |
| 14 | <https://bugzilla.libsdl.org/show_bug.cgi?id=4496>. |
| 15 | |
| 16 | CVE-2019-7572 |
| 17 | https://bugzilla.libsdl.org/show_bug.cgi?id=4495 |
| 18 | |
| 19 | Signed-off-by: Petr Písař <ppisar@redhat.com> |
| 20 | |
| 21 | # HG changeset patch |
| 22 | # User Petr Písař <ppisar@redhat.com> |
| 23 | # Date 1560041863 25200 |
| 24 | # Sat Jun 08 17:57:43 2019 -0700 |
| 25 | # Branch SDL-1.2 |
| 26 | # Node ID e52413f5258600878f9a10d2f92605a729aa8976 |
| 27 | # Parent 4e73be7b47877ae11d2279bd916910d469d18f8e |
| 28 | CVE-2019-7572: Fix a buffer overread in IMA_ADPCM_nibble |
| 29 | If an IMA ADPCM block contained an initial index out of step table |
| 30 | range (loaded in IMA_ADPCM_decode()), IMA_ADPCM_nibble() blindly used |
| 31 | this bogus value and that lead to a buffer overread. |
| 32 | |
| 33 | This patch fixes it by moving clamping the index value at the |
| 34 | beginning of IMA_ADPCM_nibble() function instead of the end after |
| 35 | an update. |
| 36 | |
| 37 | CVE-2019-7572 |
| 38 | https://bugzilla.libsdl.org/show_bug.cgi?id=4495 |
| 39 | |
| 40 | Signed-off-by: Petr Písař <ppisar@redhat.com> |
| 41 | |
| 42 | CVE: CVE-2019-7572 |
| 43 | Upstream-Status: Backport |
| 44 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| 45 | |
| 46 | diff -r faf9abbcfb5f -r a8afedbcaea0 src/audio/SDL_wave.c |
| 47 | --- a/src/audio/SDL_wave.c Mon Jun 10 08:54:29 2019 -0700 |
| 48 | +++ b/src/audio/SDL_wave.c Mon Jun 10 08:57:11 2019 -0700 |
| 49 | @@ -346,7 +346,7 @@ |
| 50 | static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
| 51 | { |
| 52 | struct IMA_ADPCM_decodestate *state; |
| 53 | - Uint8 *freeable, *encoded, *encoded_end, *decoded; |
| 54 | + Uint8 *freeable, *encoded, *encoded_end, *decoded, *decoded_end; |
| 55 | Sint32 encoded_len, samplesleft; |
| 56 | unsigned int c, channels; |
| 57 | |
| 58 | @@ -373,6 +373,7 @@ |
| 59 | return(-1); |
| 60 | } |
| 61 | decoded = *audio_buf; |
| 62 | + decoded_end = decoded + *audio_len; |
| 63 | |
| 64 | /* Get ready... Go! */ |
| 65 | while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) { |
| 66 | @@ -392,6 +393,7 @@ |
| 67 | } |
| 68 | |
| 69 | /* Store the initial sample we start with */ |
| 70 | + if (decoded + 2 > decoded_end) goto invalid_size; |
| 71 | decoded[0] = (Uint8)(state[c].sample&0xFF); |
| 72 | decoded[1] = (Uint8)(state[c].sample>>8); |
| 73 | decoded += 2; |
| 74 | @@ -402,6 +404,8 @@ |
| 75 | while ( samplesleft > 0 ) { |
| 76 | for ( c=0; c<channels; ++c ) { |
| 77 | if (encoded + 4 > encoded_end) goto invalid_size; |
| 78 | + if (decoded + 4 * 4 * channels > decoded_end) |
| 79 | + goto invalid_size; |
| 80 | Fill_IMA_ADPCM_block(decoded, encoded, |
| 81 | c, channels, &state[c]); |
| 82 | encoded += 4; |
| 83 | |
| 84 | diff -r 4e73be7b4787 -r e52413f52586 src/audio/SDL_wave.c |
| 85 | --- a/src/audio/SDL_wave.c Sat Jun 01 18:27:46 2019 +0100 |
| 86 | +++ b/src/audio/SDL_wave.c Sat Jun 08 17:57:43 2019 -0700 |
| 87 | @@ -264,6 +264,14 @@ |
| 88 | }; |
| 89 | Sint32 delta, step; |
| 90 | |
| 91 | + /* Clamp index value. The inital value can be invalid. */ |
| 92 | + if ( state->index > 88 ) { |
| 93 | + state->index = 88; |
| 94 | + } else |
| 95 | + if ( state->index < 0 ) { |
| 96 | + state->index = 0; |
| 97 | + } |
| 98 | + |
| 99 | /* Compute difference and new sample value */ |
| 100 | step = step_table[state->index]; |
| 101 | delta = step >> 3; |
| 102 | @@ -275,12 +283,6 @@ |
| 103 | |
| 104 | /* Update index value */ |
| 105 | state->index += index_table[nybble]; |
| 106 | - if ( state->index > 88 ) { |
| 107 | - state->index = 88; |
| 108 | - } else |
| 109 | - if ( state->index < 0 ) { |
| 110 | - state->index = 0; |
| 111 | - } |
| 112 | |
| 113 | /* Clamp output sample */ |
| 114 | if ( state->sample > max_audioval ) { |