blob: 63680b8b7f22138969af02f995e4a386bf552c41 [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
Brad Bishop996bc452019-12-02 13:05:15 -050050Refresh CVE-2019-7577.patch as it can't be applyed when using PATCHTOOL = "patch".
51Signed-off-by: Zheng Ruoqin <zhengrq.fnst@cn.fujitsu.com>
52---
53 src/audio/SDL_wave.c | 17 ++++++++++++++++-
54 1 file changed, 16 insertions(+), 1 deletion(-)
55
56diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
57index b4ad6c7..0bcf7e2 100644
58--- a/src/audio/SDL_wave.c
59+++ b/src/audio/SDL_wave.c
60@@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
Brad Bishop26bdd442019-08-16 17:08:17 -040061 static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
62 {
63 struct MS_ADPCM_decodestate *state[2];
64- Uint8 *freeable, *encoded, *decoded;
65+ Uint8 *freeable, *encoded, *encoded_end, *decoded;
66 Sint32 encoded_len, samplesleft;
67 Sint8 nybble, stereo;
68 Sint16 *coeff[2];
Brad Bishop996bc452019-12-02 13:05:15 -050069@@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
Brad Bishop26bdd442019-08-16 17:08:17 -040070 /* Allocate the proper sized output buffer */
71 encoded_len = *audio_len;
72 encoded = *audio_buf;
73+ encoded_end = encoded + encoded_len;
74 freeable = *audio_buf;
75 *audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) *
76 MS_ADPCM_state.wSamplesPerBlock*
Brad Bishop996bc452019-12-02 13:05:15 -050077@@ -141,10 +142,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
Brad Bishop26bdd442019-08-16 17:08:17 -040078 state[1] = &MS_ADPCM_state.state[stereo];
79 while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
80 /* Grab the initial information for this block */
81+ if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
82 state[0]->hPredictor = *encoded++;
83 if ( stereo ) {
84 state[1]->hPredictor = *encoded++;
Brad Bishop26bdd442019-08-16 17:08:17 -040085 }
86+ if (state[0]->hPredictor >= 7 || state[1]->hPredictor >= 7) {
87+ goto invalid_predictor;
88+ }
89 state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
90 encoded += sizeof(Sint16);
91 if ( stereo ) {
Brad Bishop996bc452019-12-02 13:05:15 -050092@@ -188,6 +193,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
93 samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
94 MS_ADPCM_state.wavefmt.channels;
95 while ( samplesleft > 0 ) {
96+ if (encoded + 1 > encoded_end) goto too_short;
97+
98 nybble = (*encoded)>>4;
99 new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
100 decoded[0] = new_sample&0xFF;
101@@ -209,6 +216,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
102 }
Brad Bishop26bdd442019-08-16 17:08:17 -0400103 SDL_free(freeable);
Brad Bishop996bc452019-12-02 13:05:15 -0500104 return(0);
105+too_short:
106+ SDL_SetError("Too short chunk for a MS ADPCM decoder");
107+ SDL_free(freeable);
108+ return(-1);
Brad Bishop26bdd442019-08-16 17:08:17 -0400109+invalid_predictor:
110+ SDL_SetError("Invalid predictor value for a MS ADPCM decoder");
111+ SDL_free(freeable);
112+ return(-1);
113 }
114
115 struct IMA_ADPCM_decodestate {
Brad Bishop996bc452019-12-02 13:05:15 -0500116--
1172.7.4
118