blob: 92e40aec5e300bdd615da6fddf413a81f58f75f0 [file] [log] [blame]
Brad Bishop26bdd442019-08-16 17:08:17 -04001# HG changeset patch
2# User Petr Písař <ppisar@redhat.com>
3# Date 1560182051 25200
4# Mon Jun 10 08:54:11 2019 -0700
5# Branch SDL-1.2
6# Node ID 416136310b88cbeeff8773e573e90ac1e22b3526
7# Parent a6e3d2f5183e1cc300ad993e10e9ce077e13bd9c
8CVE-2019-7577: Fix a buffer overread in MS_ADPCM_decode
9If RIFF/WAV data chunk length is shorter then expected for an audio
10format defined in preceeding RIFF/WAV format headers, a buffer
11overread can happen.
12
13This patch fixes it by checking a MS ADPCM data to be decoded are not
14past the initialized buffer.
15
16CVE-2019-7577
17Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492
18
19Signed-off-by: Petr Písař <ppisar@redhat.com>
20
21# HG changeset patch
22# User Petr Písař <ppisar@redhat.com>
23# Date 1560182069 25200
24# Mon Jun 10 08:54:29 2019 -0700
25# Branch SDL-1.2
26# Node ID faf9abbcfb5fe0d0ca23c4bf0394aa226ceccf02
27# Parent 416136310b88cbeeff8773e573e90ac1e22b3526
28CVE-2019-7577: Fix a buffer overread in MS_ADPCM_nibble and MS_ADPCM_decode
29If a chunk of RIFF/WAV file with MS ADPCM encoding contains an invalid
30predictor (a valid predictor's value is between 0 and 6 inclusive),
31a buffer overread can happen when the predictor is used as an index
32into an array of MS ADPCM coefficients.
33
34The overead happens when indexing MS_ADPCM_state.aCoeff[] array in
35MS_ADPCM_decode() and later when dereferencing a coef pointer in
36MS_ADPCM_nibble().
37
38This patch fixes it by checking the MS ADPCM predictor values fit
39into the valid range.
40
41CVE-2019-7577
42Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492
43
44Signed-off-by: Petr Písař <ppisar@redhat.com>
45
46CVE: CVE-2019-7577
47Upstream-Status: Backport
48Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
49
50diff -r a6e3d2f5183e -r 416136310b88 src/audio/SDL_wave.c
51--- a/src/audio/SDL_wave.c Mon Jun 10 08:50:59 2019 -0700
52+++ b/src/audio/SDL_wave.c Mon Jun 10 08:54:11 2019 -0700
53@@ -115,7 +115,7 @@
54 static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
55 {
56 struct MS_ADPCM_decodestate *state[2];
57- Uint8 *freeable, *encoded, *decoded;
58+ Uint8 *freeable, *encoded, *encoded_end, *decoded;
59 Sint32 encoded_len, samplesleft;
60 Sint8 nybble, stereo;
61 Sint16 *coeff[2];
62@@ -124,6 +124,7 @@
63 /* Allocate the proper sized output buffer */
64 encoded_len = *audio_len;
65 encoded = *audio_buf;
66+ encoded_end = encoded + encoded_len;
67 freeable = *audio_buf;
68 *audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) *
69 MS_ADPCM_state.wSamplesPerBlock*
70@@ -141,6 +142,7 @@
71 state[1] = &MS_ADPCM_state.state[stereo];
72 while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
73 /* Grab the initial information for this block */
74+ if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
75 state[0]->hPredictor = *encoded++;
76 if ( stereo ) {
77 state[1]->hPredictor = *encoded++;
78@@ -188,6 +190,8 @@
79 samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
80 MS_ADPCM_state.wavefmt.channels;
81 while ( samplesleft > 0 ) {
82+ if (encoded + 1 > encoded_end) goto too_short;
83+
84 nybble = (*encoded)>>4;
85 new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
86 decoded[0] = new_sample&0xFF;
87@@ -209,6 +213,10 @@
88 }
89 SDL_free(freeable);
90 return(0);
91+too_short:
92+ SDL_SetError("Too short chunk for a MS ADPCM decoder");
93+ SDL_free(freeable);
94+ return(-1);
95 }
96
97 struct IMA_ADPCM_decodestate {
98
99
100diff -r 416136310b88 -r faf9abbcfb5f src/audio/SDL_wave.c
101--- a/src/audio/SDL_wave.c Mon Jun 10 08:54:11 2019 -0700
102+++ b/src/audio/SDL_wave.c Mon Jun 10 08:54:29 2019 -0700
103@@ -147,6 +147,9 @@
104 if ( stereo ) {
105 state[1]->hPredictor = *encoded++;
106 }
107+ if (state[0]->hPredictor >= 7 || state[1]->hPredictor >= 7) {
108+ goto invalid_predictor;
109+ }
110 state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
111 encoded += sizeof(Sint16);
112 if ( stereo ) {
113@@ -217,6 +220,10 @@
114 SDL_SetError("Too short chunk for a MS ADPCM decoder");
115 SDL_free(freeable);
116 return(-1);
117+invalid_predictor:
118+ SDL_SetError("Invalid predictor value for a MS ADPCM decoder");
119+ SDL_free(freeable);
120+ return(-1);
121 }
122
123 struct IMA_ADPCM_decodestate {