CVE-2019-7573, CVE-2019-7576: Fix buffer overreads in InitMS_ADPCM SDL-1.2
authorPetr Písař <ppisar@redhat.com>
Mon, 10 Jun 2019 09:06:23 -0700
branchSDL-1.2
changeset 12819fcbecae42795
parent 12818 a8afedbcaea0
child 12821 a936f9bd3e38
CVE-2019-7573, CVE-2019-7576: Fix buffer overreads in InitMS_ADPCM
If MS ADPCM format chunk was too short, InitMS_ADPCM() parsing it
could read past the end of chunk data. This patch fixes it.

CVE-2019-7573
https://bugzilla.libsdl.org/show_bug.cgi?id=4491
CVE-2019-7576
https://bugzilla.libsdl.org/show_bug.cgi?id=4490

Signed-off-by: Petr Písař <ppisar@redhat.com>
src/audio/SDL_wave.c
     1.1 --- a/src/audio/SDL_wave.c	Mon Jun 10 08:57:11 2019 -0700
     1.2 +++ b/src/audio/SDL_wave.c	Mon Jun 10 09:06:23 2019 -0700
     1.3 @@ -44,12 +44,13 @@
     1.4  	struct MS_ADPCM_decodestate state[2];
     1.5  } MS_ADPCM_state;
     1.6  
     1.7 -static int InitMS_ADPCM(WaveFMT *format)
     1.8 +static int InitMS_ADPCM(WaveFMT *format, int length)
     1.9  {
    1.10 -	Uint8 *rogue_feel;
    1.11 +	Uint8 *rogue_feel, *rogue_feel_end;
    1.12  	int i;
    1.13  
    1.14  	/* Set the rogue pointer to the MS_ADPCM specific data */
    1.15 +	if (length < sizeof(*format)) goto too_short;
    1.16  	MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
    1.17  	MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
    1.18  	MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
    1.19 @@ -58,9 +59,11 @@
    1.20  	MS_ADPCM_state.wavefmt.bitspersample =
    1.21  					 SDL_SwapLE16(format->bitspersample);
    1.22  	rogue_feel = (Uint8 *)format+sizeof(*format);
    1.23 +	rogue_feel_end = (Uint8 *)format + length;
    1.24  	if ( sizeof(*format) == 16 ) {
    1.25  		rogue_feel += sizeof(Uint16);
    1.26  	}
    1.27 +	if (rogue_feel + 4 > rogue_feel_end) goto too_short;
    1.28  	MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
    1.29  	rogue_feel += sizeof(Uint16);
    1.30  	MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);
    1.31 @@ -70,12 +73,16 @@
    1.32  		return(-1);
    1.33  	}
    1.34  	for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) {
    1.35 +		if (rogue_feel + 4 > rogue_feel_end) goto too_short;
    1.36  		MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]);
    1.37  		rogue_feel += sizeof(Uint16);
    1.38  		MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]);
    1.39  		rogue_feel += sizeof(Uint16);
    1.40  	}
    1.41  	return(0);
    1.42 +too_short:
    1.43 +	SDL_SetError("Unexpected length of a chunk with a MS ADPCM format");
    1.44 +	return(-1);
    1.45  }
    1.46  
    1.47  static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
    1.48 @@ -495,7 +502,7 @@
    1.49  			break;
    1.50  		case MS_ADPCM_CODE:
    1.51  			/* Try to understand this */
    1.52 -			if ( InitMS_ADPCM(format) < 0 ) {
    1.53 +			if ( InitMS_ADPCM(format, lenread) < 0 ) {
    1.54  				was_error = 1;
    1.55  				goto done;
    1.56  			}