From 8bfcd9c03af5170b5003712fb77f096b5c9f341b Mon Sep 17 00:00:00 2001 From: Aayush Soni Date: Mon, 5 Jul 2021 10:11:29 +0530 Subject: sonivox: Fix global buffer overflow in WT_InterpolateNoLoop Check for loop end before accessing new samples Bug: 190286685 Test: POC in bug description Change-Id: I26a187d161d713c1a1b1b3009256acfd9e263fb3 --- arm-wt-22k/lib_src/eas_wtengine.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c index 854d4b4..68a0400 100644 --- a/arm-wt-22k/lib_src/eas_wtengine.c +++ b/arm-wt-22k/lib_src/eas_wtengine.c @@ -282,6 +282,7 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) EAS_I32 phaseFrac; EAS_I32 acc0; const EAS_SAMPLE *pSamples; + const EAS_SAMPLE *bufferEndP1; EAS_I32 samp1; EAS_I32 samp2; EAS_I32 numSamples; @@ -296,8 +297,9 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) pOutputBuffer = pWTIntFrame->pAudioBuffer; phaseInc = pWTIntFrame->frame.phaseIncrement; + bufferEndP1 = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1; pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum; - phaseFrac = (EAS_I32)pWTVoice->phaseFrac; + phaseFrac = (EAS_I32)(pWTVoice->phaseFrac & PHASE_FRAC_MASK); /* fetch adjacent samples */ #if defined(_8_BIT_SAMPLES) @@ -312,6 +314,7 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) while (numSamples--) { + EAS_I32 nextSamplePhaseInc; /* linear interpolation */ acc0 = samp2 - samp1; @@ -326,13 +329,18 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) /* increment phase */ phaseFrac += phaseInc; /*lint -e{704} */ - acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS; + nextSamplePhaseInc = phaseFrac >> NUM_PHASE_FRAC_BITS; /* next sample */ - if (acc0 > 0) { + if (nextSamplePhaseInc > 0) { + + /* check for loop end */ + if ( &pSamples[nextSamplePhaseInc+1] >= bufferEndP1) { + break; + } /* advance sample pointer */ - pSamples += acc0; + pSamples += nextSamplePhaseInc; phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK); /* fetch new samples */ -- cgit v1.2.3 From dc579832ca3a151601143a846bf2e11c5421f6c9 Mon Sep 17 00:00:00 2001 From: Aayush Soni Date: Mon, 5 Jul 2021 10:11:29 +0530 Subject: sonivox: Fix global buffer overflow in WT_InterpolateNoLoop Check for loop end before accessing new samples Bug: 190286685 Test: POC in bug description Change-Id: I26a187d161d713c1a1b1b3009256acfd9e263fb3 --- arm-wt-22k/lib_src/eas_wtengine.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c index c3012e5..950616e 100644 --- a/arm-wt-22k/lib_src/eas_wtengine.c +++ b/arm-wt-22k/lib_src/eas_wtengine.c @@ -284,6 +284,7 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) EAS_I32 phaseFrac; EAS_I32 acc0; const EAS_SAMPLE *pSamples; + const EAS_SAMPLE *bufferEndP1; EAS_I32 samp1; EAS_I32 samp2; EAS_I32 numSamples; @@ -298,8 +299,9 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) pOutputBuffer = pWTIntFrame->pAudioBuffer; phaseInc = pWTIntFrame->frame.phaseIncrement; + bufferEndP1 = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1; pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum; - phaseFrac = (EAS_I32)pWTVoice->phaseFrac; + phaseFrac = (EAS_I32)(pWTVoice->phaseFrac & PHASE_FRAC_MASK); /* fetch adjacent samples */ #if defined(_8_BIT_SAMPLES) @@ -314,6 +316,7 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) while (numSamples--) { + EAS_I32 nextSamplePhaseInc; /* linear interpolation */ acc0 = samp2 - samp1; @@ -328,13 +331,18 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) /* increment phase */ phaseFrac += phaseInc; /*lint -e{704} */ - acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS; + nextSamplePhaseInc = phaseFrac >> NUM_PHASE_FRAC_BITS; /* next sample */ - if (acc0 > 0) { + if (nextSamplePhaseInc > 0) { + + /* check for loop end */ + if ( &pSamples[nextSamplePhaseInc+1] >= bufferEndP1) { + break; + } /* advance sample pointer */ - pSamples += acc0; + pSamples += nextSamplePhaseInc; phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK); /* fetch new samples */ -- cgit v1.2.3 From 0d9f4e132732a45318e2a507c359aeef196f6635 Mon Sep 17 00:00:00 2001 From: Aayush Soni Date: Fri, 30 Jul 2021 21:32:11 +0530 Subject: sonivox: Fix global buffer overflow in WT_Interpolate Bug: 194533433 Test: atest CtsMidiTestCases atest CtsNativeMidiTestCases android.media.cts.MidiSoloTest android.media.cts.MediaPlayerTest android.mediav2.cts.ExtractorTest android.media.cts.MediaExtractorTest atest SonivoxTest -- --enable-module-dynamic-download=true Change-Id: I22c19a1367ff00e6b7db6059b6422786eb75010a (cherry picked from commit d0dbf5bd37932a53697fb0d693939420d3d28165) --- arm-wt-22k/lib_src/eas_wtengine.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c index 950616e..b1ee749 100644 --- a/arm-wt-22k/lib_src/eas_wtengine.c +++ b/arm-wt-22k/lib_src/eas_wtengine.c @@ -202,7 +202,7 @@ void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1; pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum; /*lint -e{713} truncation is OK */ - phaseFrac = pWTVoice->phaseFrac; + phaseFrac = pWTVoice->phaseFrac & PHASE_FRAC_MASK; phaseInc = pWTIntFrame->frame.phaseIncrement; /* fetch adjacent samples */ @@ -218,6 +218,8 @@ void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) while (numSamples--) { + EAS_I32 nextSamplePhaseInc; + /* linear interpolation */ acc0 = samp2 - samp1; acc0 = acc0 * phaseFrac; @@ -231,19 +233,19 @@ void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) /* increment phase */ phaseFrac += phaseInc; /*lint -e{704} */ - acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS; + nextSamplePhaseInc = phaseFrac >> NUM_PHASE_FRAC_BITS; /* next sample */ - if (acc0 > 0) { - + if (nextSamplePhaseInc > 0) { /* advance sample pointer */ - pSamples += acc0; - phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK); + pSamples += nextSamplePhaseInc; + phaseFrac = phaseFrac & PHASE_FRAC_MASK; - /* check for loop end */ - acc0 = (EAS_I32) (pSamples - loopEnd); - if (acc0 >= 0) - pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0; + /* decrementing pSamples by entire buffer length until second pSample is within */ + /* loopEnd */ + while (&pSamples[1] >= loopEnd) { + pSamples -= (loopEnd - (const EAS_SAMPLE*)pWTVoice->loopStart); + } /* fetch new samples */ #if defined(_8_BIT_SAMPLES) -- cgit v1.2.3