spxdec: Check frame sizes.
authorAndre Noll <maan@tuebingen.mpg.de>
Sat, 20 Jun 2015 21:32:13 +0000 (23:32 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 7 Feb 2016 12:46:40 +0000 (13:46 +0100)
We pass a buffer of fixed size MAX_FRAME_SIZE (defined to 2000)
to the speex decoder. This sanity check makes sure we never overrun
the buffer. Although this adds one function call per output frame,
the overhead is in the noise.

Also document MAX_FRAME_SIZE while at it.

spxdec_filter.c

index b7b6329..644d287 100644 (file)
@@ -128,7 +128,14 @@ static int speexdec_init(struct filter_node *fn)
 #define le_short(s) ((short) (s))
 #endif
 
+/**
+ * Size of the output buffer.
+ *
+ * Valid streams have frame sizes in the range from 160 to 640. To avoid buffer
+ * overflows, we bail out if the decoder reports a value bigger than this.
+ */
 #define MAX_FRAME_SIZE 2000
+
 /* Copy Ogg packet to Speex bitstream */
 static int speexdec_write_frames(int packet_no,
                struct private_spxdec_data *psd, int skip_samples,
@@ -139,7 +146,14 @@ static int speexdec_write_frames(int packet_no,
        for (j = 0; j != psd->shi.nframes; j++) {
                short output[MAX_FRAME_SIZE], *btr_output;
                int skip = skip_samples + psd->lookahead, skip_idx = 0;
-               int samples, new_frame_size = psd->shi.frame_size;
+               int samples, this_frame_size,
+                       new_frame_size = psd->shi.frame_size;
+
+               if (speex_decoder_ctl(psd->shi.state, SPEEX_GET_FRAME_SIZE,
+                               &this_frame_size) == 0) {
+                       if (this_frame_size > MAX_FRAME_SIZE)
+                               return -E_SPX_DECODE_OVERFLOW;
+               };
 
                if (speex_decode_int(psd->shi.state, &psd->bits, output) < 0)
                        return -E_SPX_DECODE;