Blame SOURCES/0001-Fix-several-memory-errors-in-the-SILK-resampler.patch

db493f
From dc58579c2c7e060084554018e9a2e8c25097a255 Mon Sep 17 00:00:00 2001
db493f
From: "Timothy B. Terriberry" <tterribe@xiph.org>
db493f
Date: Wed, 8 May 2013 10:25:52 -0700
db493f
Subject: [PATCH] Fix several memory errors in the SILK resampler.
db493f
db493f
1) The memcpy's were using sizeof(opus_int32), but the type of the
db493f
    local buffer was opus_int16.
db493f
2) Because the size was wrong, this potentially allowed the source
db493f
    and destination regions of the memcpy overlap.
db493f
   I _believe_ that nSamplesIn is at least fs_in_khZ, which is at
db493f
    least 8.
db493f
   Since RESAMPLER_ORDER_FIR_12 is only 8, I don't think that's a
db493f
    problem once you fix the type size.
db493f
3) The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the
db493f
    data stored in it was actually _twice_ the input batch size
db493f
    (nSamplesIn<<1).
db493f
db493f
Because this never blew up in testing, I suspect that in practice
db493f
 the batch sizes are reasonable enough that none of these things
db493f
 was ever a problem, but proving that seems non-obvious.
db493f
db493f
This patch just converts the whole thing to use CELT's vararrays.
db493f
This fixes the buffer size problems (since we allocate a buffer
db493f
 with the actual size we use) and gets these large buffers off the
db493f
 stack on devices using the pseudo-stack.
db493f
It also fixes the memcpy problems by changing the sizeof to
db493f
 opus_int16.
db493f
It turns out sFIR, which saved state between calls, was being used
db493f
 elsewhere as opus_int32, so this converts it to a union to make
db493f
 this sharing explicit.
db493f
---
db493f
 silk/resampler_private_IIR_FIR.c  | 14 +++++++++-----
db493f
 silk/resampler_private_down_FIR.c |  4 ++--
db493f
 silk/resampler_structs.h          |  5 ++++-
db493f
 3 files changed, 15 insertions(+), 8 deletions(-)
db493f
db493f
diff --git a/silk/resampler_private_IIR_FIR.c b/silk/resampler_private_IIR_FIR.c
db493f
index d9e42ca..2b9602d 100644
db493f
--- a/silk/resampler_private_IIR_FIR.c
db493f
+++ b/silk/resampler_private_IIR_FIR.c
db493f
@@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
db493f
 
db493f
 #include "SigProc_FIX.h"
db493f
 #include "resampler_private.h"
db493f
+#include "stack_alloc.h"
db493f
 
db493f
 static inline opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL(
db493f
     opus_int16  *out,
db493f
@@ -71,10 +72,13 @@ void silk_resampler_private_IIR_FIR(
db493f
     silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
db493f
     opus_int32 nSamplesIn;
db493f
     opus_int32 max_index_Q16, index_increment_Q16;
db493f
-    opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
db493f
+    VARDECL( opus_int16, buf );
db493f
+    SAVE_STACK;
db493f
+
db493f
+    ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 );
db493f
 
db493f
     /* Copy buffered samples to start of buffer */
db493f
-    silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
db493f
+    silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
db493f
 
db493f
     /* Iterate over blocks of frameSizeIn input samples */
db493f
     index_increment_Q16 = S->invRatio_Q16;
db493f
@@ -91,13 +95,13 @@ void silk_resampler_private_IIR_FIR(
db493f
 
db493f
         if( inLen > 0 ) {
db493f
             /* More iterations to do; copy last part of filtered signal to beginning of buffer */
db493f
-            silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
db493f
+            silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
db493f
         } else {
db493f
             break;
db493f
         }
db493f
     }
db493f
 
db493f
     /* Copy last part of filtered signal to the state for the next call */
db493f
-    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
db493f
+    silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
db493f
+    RESTORE_STACK;
db493f
 }
db493f
-
db493f
diff --git a/silk/resampler_private_down_FIR.c b/silk/resampler_private_down_FIR.c
db493f
index 5d24564..8bedb0d 100644
db493f
--- a/silk/resampler_private_down_FIR.c
db493f
+++ b/silk/resampler_private_down_FIR.c
db493f
@@ -155,7 +155,7 @@ void silk_resampler_private_down_FIR(
db493f
     const opus_int16 *FIR_Coefs;
db493f
 
db493f
     /* Copy buffered samples to start of buffer */
db493f
-    silk_memcpy( buf, S->sFIR, S->FIR_Order * sizeof( opus_int32 ) );
db493f
+    silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) );
db493f
 
db493f
     FIR_Coefs = &S->Coefs[ 2 ];
db493f
 
db493f
@@ -185,5 +185,5 @@ void silk_resampler_private_down_FIR(
db493f
     }
db493f
 
db493f
     /* Copy last part of filtered signal to the state for the next call */
db493f
-    silk_memcpy( S->sFIR, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
db493f
+    silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
db493f
 }
db493f
diff --git a/silk/resampler_structs.h b/silk/resampler_structs.h
db493f
index 4c28bd0..d1a0b95 100644
db493f
--- a/silk/resampler_structs.h
db493f
+++ b/silk/resampler_structs.h
db493f
@@ -37,7 +37,10 @@ extern "C" {
db493f
 
db493f
 typedef struct _silk_resampler_state_struct{
db493f
     opus_int32       sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */
db493f
-    opus_int32       sFIR[ SILK_RESAMPLER_MAX_FIR_ORDER ];
db493f
+    union{
db493f
+        opus_int32   i32[ SILK_RESAMPLER_MAX_FIR_ORDER ];
db493f
+        opus_int16   i16[ SILK_RESAMPLER_MAX_FIR_ORDER ];
db493f
+    }                sFIR;
db493f
     opus_int16       delayBuf[ 48 ];
db493f
     opus_int         resampler_function;
db493f
     opus_int         batchSize;
db493f
-- 
db493f
1.8.4.2
db493f