shithub: opus

Download patch

ref: cae4445fb7f9bae2e2f318969e1f779729f3c0d1
parent: 65f11d326db773b2353d5066fd6b9191e9b3df81
author: Andrew Allen <bitllama@google.com>
date: Mon Dec 4 11:05:57 EST 2017

Ensure mapping matrix size is always valid.

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>

--- a/src/mapping_matrix.c
+++ b/src/mapping_matrix.c
@@ -39,9 +39,21 @@
 
 #define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
 
-int mapping_matrix_get_size(int rows, int cols)
+opus_int32 mapping_matrix_get_size(int rows, int cols)
 {
-  return align(sizeof(MappingMatrix)) + align(rows * cols * sizeof(opus_int16));
+  opus_int32 size;
+
+  /* Mapping Matrix must only support up to 255 channels in or out.
+   * Additionally, the total cell count must be <= 65004 octets in order
+   * for the matrix to be stored in an OGG header.
+   */
+  if (rows > 255 || cols > 255)
+      return 0;
+  size = rows * (opus_int32)cols * sizeof(opus_int16);
+  if (size > 65004)
+    return 0;
+
+  return align(sizeof(MappingMatrix)) + align(size);
 }
 
 opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
--- a/src/mapping_matrix.h
+++ b/src/mapping_matrix.h
@@ -50,7 +50,7 @@
     /* Matrix cell data goes here using col-wise ordering. */
 } MappingMatrix;
 
-int mapping_matrix_get_size(int rows, int cols);
+opus_int32 mapping_matrix_get_size(int rows, int cols);
 
 opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
 
--- a/src/opus_projection_decoder.c
+++ b/src/opus_projection_decoder.c
@@ -110,6 +110,9 @@
 
   matrix_size =
     mapping_matrix_get_size(streams + coupled_streams, channels);
+  if (!matrix_size)
+    return 0;
+
   decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
   if (!decoder_size)
     return 0;
@@ -147,7 +150,14 @@
   }
 
   /* Assign demixing matrix. */
-  st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(channels, nb_input_streams);
+  st->demixing_matrix_size_in_bytes =
+    mapping_matrix_get_size(channels, nb_input_streams);
+  if (!st->demixing_matrix_size_in_bytes)
+  {
+    RESTORE_STACK;
+    return OPUS_BAD_ARG;
+  }
+
   mapping_matrix_init(get_demixing_matrix(st), channels, nb_input_streams, 0,
     buf, demixing_matrix_size);
 
--- a/src/opus_projection_encoder.c
+++ b/src/opus_projection_encoder.c
@@ -150,6 +150,9 @@
 
   matrix_rows = order_plus_one * order_plus_one + 2;
   matrix_size = mapping_matrix_get_size(matrix_rows, matrix_rows);
+  if (!matrix_size)
+    return 0;
+
   encoder_size =
       opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
   if (!encoder_size)
@@ -210,6 +213,8 @@
     }
     st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
       mixing_matrix->rows, mixing_matrix->cols);
+    if (!st->mixing_matrix_size_in_bytes)
+      return OPUS_BAD_ARG;
 
     /* Assign demixing matrix based on available pre-computed matrices. */
     demixing_matrix = get_demixing_matrix(st);
@@ -233,6 +238,8 @@
     }
     st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
       demixing_matrix->rows, demixing_matrix->cols);
+    if (!st->demixing_matrix_size_in_bytes)
+      return OPUS_BAD_ARG;
   }
   else
     return OPUS_UNIMPLEMENTED;
--- a/tests/test_opus_projection.c
+++ b/tests/test_opus_projection.c
@@ -96,6 +96,7 @@
     -29491, 3277, 0, -3277};
 
   int i, ret;
+  opus_int32 simple_matrix_size;
   opus_val16 *input_val16;
   opus_val16 *output_val16;
   opus_int16 *output_int16;
@@ -107,9 +108,12 @@
   output_val16 = (opus_val16 *)opus_alloc(align(sizeof(opus_val16) * SIMPLE_MATRIX_OUTPUT_SIZE));
 
   /* Initialize matrix */
-  simple_matrix = (MappingMatrix *)opus_alloc(
-    mapping_matrix_get_size(simple_matrix_params.rows,
-                            simple_matrix_params.cols));
+  simple_matrix_size = mapping_matrix_get_size(simple_matrix_params.rows,
+    simple_matrix_params.cols);
+  if (!simple_matrix_size)
+    test_failed();
+
+  simple_matrix = (MappingMatrix *)opus_alloc(simple_matrix_size);
   mapping_matrix_init(simple_matrix, simple_matrix_params.rows,
     simple_matrix_params.cols, simple_matrix_params.gain, simple_matrix_data,
     sizeof(simple_matrix_data));