1# 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
50Refresh 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,
61 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];
69@@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
70 	/* 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*
77@@ -141,10 +142,14 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
78 	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++;
85 		}
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 ) {
92@@ -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 	}
103 	SDL_free(freeable);
104 	return(0);
105+too_short:
106+	SDL_SetError("Too short chunk for a MS ADPCM decoder");
107+	SDL_free(freeable);
108+	return(-1);
109+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 {
116--
1172.7.4
118
119