SDL-1.2.15-CVE-2019-7577-Fix-a-buffer-overread-in-MS_ADPCM_deco.patch 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. From ac3d0d365b1f01a6782565feda0c7432a5795671 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
  3. Date: Thu, 14 Feb 2019 14:12:22 +0100
  4. Subject: [PATCH] CVE-2019-7577: Fix a buffer overread in MS_ADPCM_decode
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. If RIFF/WAV data chunk length is shorter then expected for an audio
  9. format defined in preceeding RIFF/WAV format headers, a buffer
  10. overread can happen.
  11. This patch fixes it by checking a MS ADPCM data to be decoded are not
  12. past the initialized buffer.
  13. CVE-2019-7577
  14. Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492
  15. Signed-off-by: Petr Písař <ppisar@redhat.com>
  16. ---
  17. src/audio/SDL_wave.c | 10 +++++++++-
  18. 1 file changed, 9 insertions(+), 1 deletion(-)
  19. diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
  20. index b4ad6c7..e42d01c 100644
  21. --- a/src/audio/SDL_wave.c
  22. +++ b/src/audio/SDL_wave.c
  23. @@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
  24. static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
  25. {
  26. struct MS_ADPCM_decodestate *state[2];
  27. - Uint8 *freeable, *encoded, *decoded;
  28. + Uint8 *freeable, *encoded, *encoded_end, *decoded;
  29. Sint32 encoded_len, samplesleft;
  30. Sint8 nybble, stereo;
  31. Sint16 *coeff[2];
  32. @@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
  33. /* Allocate the proper sized output buffer */
  34. encoded_len = *audio_len;
  35. encoded = *audio_buf;
  36. + encoded_end = encoded + encoded_len;
  37. freeable = *audio_buf;
  38. *audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) *
  39. MS_ADPCM_state.wSamplesPerBlock*
  40. @@ -141,6 +142,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
  41. state[1] = &MS_ADPCM_state.state[stereo];
  42. while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
  43. /* Grab the initial information for this block */
  44. + if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
  45. state[0]->hPredictor = *encoded++;
  46. if ( stereo ) {
  47. state[1]->hPredictor = *encoded++;
  48. @@ -188,6 +190,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
  49. samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
  50. MS_ADPCM_state.wavefmt.channels;
  51. while ( samplesleft > 0 ) {
  52. + if (encoded + 1 > encoded_end) goto too_short;
  53. +
  54. nybble = (*encoded)>>4;
  55. new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
  56. decoded[0] = new_sample&0xFF;
  57. @@ -209,6 +213,10 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
  58. }
  59. SDL_free(freeable);
  60. return(0);
  61. +too_short:
  62. + SDL_SetError("Too short chunk for a MS ADPCM decoder");
  63. + SDL_free(freeable);
  64. + return(-1);
  65. }
  66. struct IMA_ADPCM_decodestate {
  67. --
  68. 2.20.1