@@ -72,12 +72,13 @@ static void eq_fir_free_delaylines(struct processing_module *mod)
7272}
7373
7474static int eq_fir_init_coef (struct comp_dev * dev , struct sof_eq_fir_config * config ,
75- struct fir_state_32x16 * fir , int nch )
75+ size_t config_size , struct fir_state_32x16 * fir , int nch )
7676{
7777 struct sof_fir_coef_data * lookup [SOF_EQ_FIR_MAX_RESPONSES ];
7878 struct sof_fir_coef_data * eq ;
7979 int16_t * assign_response ;
8080 int16_t * coef_data ;
81+ size_t coef_words_max ;
8182 size_t size_sum = 0 ;
8283 int resp = 0 ;
8384 int i ;
@@ -101,6 +102,11 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf
101102 config -> number_of_responses , config -> channels_in_config , nch );
102103
103104 /* Sanity checks */
105+ if (config -> size != config_size ) {
106+ comp_err (dev , "Incorrect configuration blob size" );
107+ return - EINVAL ;
108+ }
109+
104110 if (nch > PLATFORM_MAX_CHANNELS ||
105111 config -> channels_in_config > PLATFORM_MAX_CHANNELS ||
106112 !config -> channels_in_config ) {
@@ -112,16 +118,45 @@ static int eq_fir_init_coef(struct comp_dev *dev, struct sof_eq_fir_config *conf
112118 return - EINVAL ;
113119 }
114120
121+ /* Compute the size of the coefficient area in int16_t words from the
122+ * blob's self-declared size. The blob layout is:
123+ * sizeof(*config) header bytes
124+ * channels_in_config int16_t assign_response[]
125+ * coefficient data[]
126+ */
127+ if (config -> size < sizeof (* config ) ||
128+ config -> size - sizeof (* config ) <
129+ (size_t )config -> channels_in_config * sizeof (int16_t )) {
130+ comp_err (dev , "config size %u too small" , config -> size );
131+ return - EINVAL ;
132+ }
133+ coef_words_max = (config -> size - sizeof (* config )) / sizeof (int16_t ) -
134+ config -> channels_in_config ;
135+
115136 /* Collect index of response start positions in all_coefficients[] */
116137 j = 0 ;
117138 assign_response = ASSUME_ALIGNED (& config -> data [0 ], 4 );
118- coef_data = ASSUME_ALIGNED (& config -> data [config -> channels_in_config ],
119- 4 );
139+ coef_data = ASSUME_ALIGNED (& config -> data [config -> channels_in_config ], 4 );
120140 for (i = 0 ; i < SOF_EQ_FIR_MAX_RESPONSES ; i ++ ) {
121141 if (i < config -> number_of_responses ) {
142+ /* Header must fit before reading length */
143+ if (j + SOF_FIR_COEF_NHEADER > coef_words_max ) {
144+ comp_err (dev , "response %d header out of bounds" , i );
145+ return - EINVAL ;
146+ }
122147 eq = (struct sof_fir_coef_data * )& coef_data [j ];
148+ /* Bound length so it is valid and the coefficient data
149+ * stays within the blob.
150+ */
151+ if (eq -> length <= 0 || eq -> length > SOF_FIR_MAX_LENGTH ||
152+ (eq -> length & 0x3 ) ||
153+ j + SOF_FIR_COEF_NHEADER + eq -> length > coef_words_max ) {
154+ comp_err (dev , "response %d length %d out of bounds" ,
155+ i , eq -> length );
156+ return - EINVAL ;
157+ }
123158 lookup [i ] = eq ;
124- j += SOF_FIR_COEF_NHEADER + coef_data [ j ] ;
159+ j += SOF_FIR_COEF_NHEADER + eq -> length ;
125160 } else {
126161 lookup [i ] = NULL ;
127162 }
@@ -209,7 +244,7 @@ static int eq_fir_setup(struct processing_module *mod, int nch)
209244 cd -> nch = nch ;
210245
211246 /* Set coefficients for each channel EQ from coefficient blob */
212- delay_size = eq_fir_init_coef (dev , cd -> config , cd -> fir , nch );
247+ delay_size = eq_fir_init_coef (dev , cd -> config , cd -> config_size , cd -> fir , nch );
213248 if (delay_size < 0 )
214249 return delay_size ; /* Contains error code */
215250
@@ -236,7 +271,7 @@ static int eq_fir_setup(struct processing_module *mod, int nch)
236271
237272static int eq_fir_validator (struct comp_dev * dev , void * new_data , uint32_t new_data_size )
238273{
239- return eq_fir_init_coef (dev , new_data , NULL , -1 );
274+ return eq_fir_init_coef (dev , new_data , new_data_size , NULL , -1 );
240275}
241276
242277/*
@@ -332,7 +367,13 @@ static int eq_fir_process(struct processing_module *mod,
332367
333368 /* Check for changed configuration */
334369 if (comp_is_new_data_blob_available (cd -> model_handler )) {
335- cd -> config = comp_get_data_blob (cd -> model_handler , NULL , NULL );
370+ cd -> config = comp_get_data_blob (cd -> model_handler , & cd -> config_size , NULL );
371+ if (!cd -> config || cd -> config_size < sizeof (* cd -> config ) ||
372+ cd -> config_size > SOF_EQ_FIR_MAX_SIZE ) {
373+ comp_err (mod -> dev , "invalid configuration blob, size %zu" ,
374+ cd -> config_size );
375+ return - EINVAL ;
376+ }
336377 ret = eq_fir_setup (mod , audio_stream_get_channels (source ));
337378 if (ret < 0 ) {
338379 comp_err (mod -> dev , "failed FIR setup" );
@@ -384,7 +425,6 @@ static int eq_fir_prepare(struct processing_module *mod,
384425 int channels ;
385426 enum sof_ipc_frame frame_fmt ;
386427 int ret = 0 ;
387- size_t data_size ;
388428
389429 comp_dbg (dev , "entry" );
390430
@@ -407,8 +447,15 @@ static int eq_fir_prepare(struct processing_module *mod,
407447 frame_fmt = audio_stream_get_frm_fmt (& sourceb -> stream );
408448
409449 cd -> eq_fir_func = eq_fir_passthrough ;
410- cd -> config = comp_get_data_blob (cd -> model_handler , & data_size , NULL );
411- if (cd -> config && data_size > 0 ) {
450+ cd -> config = comp_get_data_blob (cd -> model_handler , & cd -> config_size , NULL );
451+ if (cd -> config ) {
452+ if (cd -> config_size < sizeof (* cd -> config ) ||
453+ cd -> config_size > SOF_EQ_FIR_MAX_SIZE ) {
454+ comp_err (dev , "invalid configuration blob, size %zu" ,
455+ cd -> config_size );
456+ comp_set_state (dev , COMP_TRIGGER_RESET );
457+ return - EINVAL ;
458+ }
412459 ret = eq_fir_setup (mod , channels );
413460 if (ret < 0 )
414461 comp_err (dev , "eq_fir_setup failed." );
0 commit comments