@@ -239,59 +239,111 @@ static int eq_iir_init_response(struct comp_dev *dev, int idx,
239239 return 0 ;
240240}
241241
242- static int eq_iir_init_coef (struct processing_module * mod , int nch )
242+ /* Validate the config blob layout and, if lookup is non-NULL, populate it
243+ * with pointers to each response header. Pass lookup = NULL to validate only.
244+ */
245+ static int eq_iir_walk_config (struct comp_dev * dev ,
246+ struct sof_eq_iir_config * config ,
247+ size_t config_size ,
248+ struct sof_eq_iir_header * * lookup )
243249{
244- struct comp_data * cd = module_get_private_data (mod );
245- struct sof_eq_iir_config * config = cd -> config ;
246- struct iir_state_df1 * iir = cd -> iir ;
247- struct sof_eq_iir_header * lookup [SOF_EQ_IIR_MAX_RESPONSES ];
248250 struct sof_eq_iir_header * eq ;
249251 uint32_t coef_words_max ;
250- int32_t * assign_response ;
251252 int32_t * coef_data ;
252- int size_sum = 0 ;
253- int resp = 0 ;
253+ int ret ;
254254 int i ;
255255 uint32_t j ;
256- int s ;
257- int ret ;
258256
259- comp_info (mod -> dev , "%u responses, %u channels, stream %d channels" ,
260- config -> number_of_responses , config -> channels_in_config , nch );
261-
262- /* Sanity checks */
263- if (nch > PLATFORM_MAX_CHANNELS ||
264- config -> channels_in_config > PLATFORM_MAX_CHANNELS ||
257+ if (config -> channels_in_config > PLATFORM_MAX_CHANNELS ||
265258 !config -> channels_in_config ) {
266- comp_err (mod -> dev , "invalid channels count" );
259+ comp_err (dev , "invalid channels_in_config %u" , config -> channels_in_config );
267260 return - EINVAL ;
268261 }
269262 if (config -> number_of_responses > SOF_EQ_IIR_MAX_RESPONSES ) {
270- comp_err (mod -> dev , "# of resp exceeds max" );
263+ comp_err (dev , "# of resp %u exceeds max" , config -> number_of_responses );
271264 return - EINVAL ;
272265 }
273266
274- ret = eq_iir_blob_words_max (mod -> dev , config , cd -> config_size , & coef_words_max );
267+ ret = eq_iir_blob_words_max (dev , config , config_size , & coef_words_max );
275268 if (ret < 0 )
276269 return ret ;
277270
278- /* Collect index of response start positions in all_coefficients[] */
279271 j = 0 ;
280- assign_response = ASSUME_ALIGNED (& config -> data [0 ], 4 );
281272 coef_data = ASSUME_ALIGNED (& config -> data [config -> channels_in_config ], 4 );
282- for (i = 0 ; i < SOF_EQ_IIR_MAX_RESPONSES ; i ++ ) {
283- if (i < config -> number_of_responses ) {
284- ret = eq_iir_init_response (mod -> dev , i , coef_data ,
285- coef_words_max , & j , & eq );
286- if (ret < 0 )
287- return ret ;
273+ for (i = 0 ; i < config -> number_of_responses ; i ++ ) {
274+ ret = eq_iir_init_response (dev , i , coef_data , coef_words_max , & j , & eq );
275+ if (ret < 0 )
276+ return ret ;
277+ if (lookup )
288278 lookup [i ] = eq ;
289- } else {
279+ }
280+ if (lookup ) {
281+ for (; i < SOF_EQ_IIR_MAX_RESPONSES ; i ++ )
290282 lookup [i ] = NULL ;
283+ }
284+
285+ return 0 ;
286+ }
287+
288+ int eq_iir_validate_config (struct comp_dev * dev ,
289+ struct sof_eq_iir_config * config ,
290+ size_t config_size )
291+ {
292+ int32_t * assign_response ;
293+ int32_t resp ;
294+ int ret ;
295+ int i ;
296+
297+ ret = eq_iir_walk_config (dev , config , config_size , NULL );
298+ if (ret < 0 )
299+ return ret ;
300+
301+ /* Validate every assign_response[] entry that the per-channel loop in
302+ * eq_iir_init_coef() could pick up. Entries beyond channels_in_config
303+ * reuse the last assigned value, so checking [0, channels_in_config)
304+ * covers all reachable nch.
305+ */
306+ assign_response = ASSUME_ALIGNED (& config -> data [0 ], 4 );
307+ for (i = 0 ; i < config -> channels_in_config ; i ++ ) {
308+ resp = assign_response [i ];
309+ if (resp >= 0 && resp >= config -> number_of_responses ) {
310+ comp_err (dev , "assign_response[%d] = %d exceeds %u" ,
311+ i , resp , config -> number_of_responses );
312+ return - EINVAL ;
291313 }
292314 }
293315
316+ return 0 ;
317+ }
318+
319+ static int eq_iir_init_coef (struct processing_module * mod , int nch )
320+ {
321+ struct comp_data * cd = module_get_private_data (mod );
322+ struct sof_eq_iir_config * config = cd -> config ;
323+ struct iir_state_df1 * iir = cd -> iir ;
324+ struct sof_eq_iir_header * lookup [SOF_EQ_IIR_MAX_RESPONSES ];
325+ struct sof_eq_iir_header * eq ;
326+ int32_t * assign_response ;
327+ int size_sum = 0 ;
328+ int resp = 0 ;
329+ int i ;
330+ int s ;
331+ int ret ;
332+
333+ comp_info (mod -> dev , "%u responses, %u channels, stream %d channels" ,
334+ config -> number_of_responses , config -> channels_in_config , nch );
335+
336+ if (nch > PLATFORM_MAX_CHANNELS ) {
337+ comp_err (mod -> dev , "invalid stream channels %d" , nch );
338+ return - EINVAL ;
339+ }
340+
341+ ret = eq_iir_walk_config (mod -> dev , config , cd -> config_size , lookup );
342+ if (ret < 0 )
343+ return ret ;
344+
294345 /* Initialize 1st phase */
346+ assign_response = ASSUME_ALIGNED (& config -> data [0 ], 4 );
295347 for (i = 0 ; i < nch ; i ++ ) {
296348 /* Check for not reading past blob response to channel assign
297349 * map. The previous channel response is assigned for any
0 commit comments