1*4882a593Smuzhiyun# HG changeset patch
2*4882a593Smuzhiyun# User Petr Písař <ppisar@redhat.com>
3*4882a593Smuzhiyun# Date 1560183905 25200
4*4882a593Smuzhiyun#      Mon Jun 10 09:25:05 2019 -0700
5*4882a593Smuzhiyun# Branch SDL-1.2
6*4882a593Smuzhiyun# Node ID a936f9bd3e381d67d8ddee8b9243f85799ea4798
7*4882a593Smuzhiyun# Parent  fcbecae427951bac1684baaba2ade68221315140
8*4882a593SmuzhiyunCVE-2019-7575: Fix a buffer overwrite in MS_ADPCM_decode
9*4882a593SmuzhiyunIf a WAV format defines shorter audio stream and decoded MS ADPCM data chunk
10*4882a593Smuzhiyunis longer, decoding continued past the output audio buffer.
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunThis fix is based on a patch from
13*4882a593Smuzhiyun<https://bugzilla.libsdl.org/show_bug.cgi?id=4492>.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyunhttps://bugzilla.libsdl.org/show_bug.cgi?id=4493
16*4882a593SmuzhiyunCVE-2019-7575
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunSigned-off-by: Petr Písař <ppisar@redhat.com>
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunCVE: CVE-2019-7575
21*4882a593SmuzhiyunUpstream-Status: Backport
22*4882a593SmuzhiyunSigned-off-by: Anuj Mittal <anuj.mittal@intel.com>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyundiff -r fcbecae42795 -r a936f9bd3e38 src/audio/SDL_wave.c
25*4882a593Smuzhiyun--- a/src/audio/SDL_wave.c	Mon Jun 10 09:06:23 2019 -0700
26*4882a593Smuzhiyun+++ b/src/audio/SDL_wave.c	Mon Jun 10 09:25:05 2019 -0700
27*4882a593Smuzhiyun@@ -122,7 +122,7 @@
28*4882a593Smuzhiyun static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	struct MS_ADPCM_decodestate *state[2];
31*4882a593Smuzhiyun-	Uint8 *freeable, *encoded, *encoded_end, *decoded;
32*4882a593Smuzhiyun+	Uint8 *freeable, *encoded, *encoded_end, *decoded, *decoded_end;
33*4882a593Smuzhiyun 	Sint32 encoded_len, samplesleft;
34*4882a593Smuzhiyun 	Sint8 nybble, stereo;
35*4882a593Smuzhiyun 	Sint16 *coeff[2];
36*4882a593Smuzhiyun@@ -142,6 +142,7 @@
37*4882a593Smuzhiyun 		return(-1);
38*4882a593Smuzhiyun 	}
39*4882a593Smuzhiyun 	decoded = *audio_buf;
40*4882a593Smuzhiyun+	decoded_end = decoded + *audio_len;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun 	/* Get ready... Go! */
43*4882a593Smuzhiyun 	stereo = (MS_ADPCM_state.wavefmt.channels == 2);
44*4882a593Smuzhiyun@@ -149,7 +150,7 @@
45*4882a593Smuzhiyun 	state[1] = &MS_ADPCM_state.state[stereo];
46*4882a593Smuzhiyun 	while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
47*4882a593Smuzhiyun 		/* Grab the initial information for this block */
48*4882a593Smuzhiyun-		if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
49*4882a593Smuzhiyun+		if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto invalid_size;
50*4882a593Smuzhiyun 		state[0]->hPredictor = *encoded++;
51*4882a593Smuzhiyun 		if ( stereo ) {
52*4882a593Smuzhiyun 			state[1]->hPredictor = *encoded++;
53*4882a593Smuzhiyun@@ -179,6 +180,7 @@
54*4882a593Smuzhiyun 		coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun 		/* Store the two initial samples we start with */
57*4882a593Smuzhiyun+		if (decoded + 4 + (stereo ? 4 : 0) > decoded_end) goto invalid_size;
58*4882a593Smuzhiyun 		decoded[0] = state[0]->iSamp2&0xFF;
59*4882a593Smuzhiyun 		decoded[1] = state[0]->iSamp2>>8;
60*4882a593Smuzhiyun 		decoded += 2;
61*4882a593Smuzhiyun@@ -200,7 +202,8 @@
62*4882a593Smuzhiyun 		samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
63*4882a593Smuzhiyun 					MS_ADPCM_state.wavefmt.channels;
64*4882a593Smuzhiyun 		while ( samplesleft > 0 ) {
65*4882a593Smuzhiyun-			if (encoded + 1 > encoded_end) goto too_short;
66*4882a593Smuzhiyun+			if (encoded + 1 > encoded_end) goto invalid_size;
67*4882a593Smuzhiyun+			if (decoded + 4 > decoded_end) goto invalid_size;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun 			nybble = (*encoded)>>4;
70*4882a593Smuzhiyun 			new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
71*4882a593Smuzhiyun@@ -223,8 +226,8 @@
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 	SDL_free(freeable);
74*4882a593Smuzhiyun 	return(0);
75*4882a593Smuzhiyun-too_short:
76*4882a593Smuzhiyun-	SDL_SetError("Too short chunk for a MS ADPCM decoder");
77*4882a593Smuzhiyun+invalid_size:
78*4882a593Smuzhiyun+	SDL_SetError("Unexpected chunk length for a MS ADPCM decoder");
79*4882a593Smuzhiyun 	SDL_free(freeable);
80*4882a593Smuzhiyun 	return(-1);
81*4882a593Smuzhiyun invalid_predictor:
82