@@ -180,20 +180,81 @@ void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffe
180180}
181181#endif /* CONFIG_FORMAT_S32LE */
182182
183+ static int eq_iir_blob_words_max (struct comp_dev * dev ,
184+ const struct sof_eq_iir_config * config ,
185+ size_t blob_size ,
186+ uint32_t * coef_words_max )
187+ {
188+ size_t payload_bytes ;
189+
190+ /* Compute the size of the coefficient area in int32_t words from the
191+ * framework-reported blob size. The blob layout is:
192+ * sizeof(*config) header bytes
193+ * channels_in_config int32_t assign_response[]
194+ * coefficient data[]
195+ * channels_in_config is bounded above, so the multiply fits in size_t.
196+ * The blob's self-declared config->size is cross-checked against the
197+ * authoritative blob_size so all later parsing stays within the buffer.
198+ */
199+ if (blob_size < sizeof (* config ) || config -> size != blob_size ) {
200+ comp_err (dev , "blob size %zu / header size %u mismatch or too small" ,
201+ blob_size , config -> size );
202+ return - EINVAL ;
203+ }
204+ payload_bytes = blob_size - sizeof (* config );
205+ if (payload_bytes % sizeof (int32_t ) ||
206+ payload_bytes < (size_t )config -> channels_in_config * sizeof (int32_t )) {
207+ comp_err (dev , "blob size %zu misaligned or too small" , blob_size );
208+ return - EINVAL ;
209+ }
210+ * coef_words_max = payload_bytes / sizeof (int32_t ) - config -> channels_in_config ;
211+ return 0 ;
212+ }
213+
214+ static int eq_iir_init_response (struct comp_dev * dev , int idx ,
215+ int32_t * coef_data , uint32_t coef_words_max ,
216+ uint32_t * j , struct sof_eq_iir_header * * eq_out )
217+ {
218+ struct sof_eq_iir_header * eq ;
219+ uint32_t header_end = * j + SOF_EQ_IIR_NHEADER ;
220+ uint32_t section_end ;
221+
222+ /* Header must fit before reading num_sections */
223+ if (header_end > coef_words_max ) {
224+ comp_err (dev , "response %d header out of bounds" , idx );
225+ return - EINVAL ;
226+ }
227+ eq = (struct sof_eq_iir_header * )& coef_data [* j ];
228+ /* Bound num_sections so the multiply cannot overflow and the section
229+ * data stays within the blob.
230+ */
231+ section_end = header_end + (uint32_t )SOF_EQ_IIR_NBIQUAD * eq -> num_sections ;
232+ if (eq -> num_sections > SOF_EQ_IIR_BIQUADS_MAX || section_end > coef_words_max ) {
233+ comp_err (dev , "response %d num_sections %u out of bounds" ,
234+ idx , eq -> num_sections );
235+ return - EINVAL ;
236+ }
237+ * eq_out = eq ;
238+ * j = section_end ;
239+ return 0 ;
240+ }
241+
183242static int eq_iir_init_coef (struct processing_module * mod , int nch )
184243{
185244 struct comp_data * cd = module_get_private_data (mod );
186245 struct sof_eq_iir_config * config = cd -> config ;
187246 struct iir_state_df1 * iir = cd -> iir ;
188247 struct sof_eq_iir_header * lookup [SOF_EQ_IIR_MAX_RESPONSES ];
189248 struct sof_eq_iir_header * eq ;
249+ uint32_t coef_words_max ;
190250 int32_t * assign_response ;
191251 int32_t * coef_data ;
192252 int size_sum = 0 ;
193253 int resp = 0 ;
194254 int i ;
195- int j ;
255+ uint32_t j ;
196256 int s ;
257+ int ret ;
197258
198259 comp_info (mod -> dev , "%u responses, %u channels, stream %d channels" ,
199260 config -> number_of_responses , config -> channels_in_config , nch );
@@ -210,17 +271,21 @@ static int eq_iir_init_coef(struct processing_module *mod, int nch)
210271 return - EINVAL ;
211272 }
212273
274+ ret = eq_iir_blob_words_max (mod -> dev , config , cd -> config_size , & coef_words_max );
275+ if (ret < 0 )
276+ return ret ;
277+
213278 /* Collect index of response start positions in all_coefficients[] */
214279 j = 0 ;
215280 assign_response = ASSUME_ALIGNED (& config -> data [0 ], 4 );
216- coef_data = ASSUME_ALIGNED (& config -> data [config -> channels_in_config ],
217- 4 );
281+ coef_data = ASSUME_ALIGNED (& config -> data [config -> channels_in_config ], 4 );
218282 for (i = 0 ; i < SOF_EQ_IIR_MAX_RESPONSES ; i ++ ) {
219283 if (i < config -> number_of_responses ) {
220- eq = (struct sof_eq_iir_header * )& coef_data [j ];
284+ ret = eq_iir_init_response (mod -> dev , i , coef_data ,
285+ coef_words_max , & j , & eq );
286+ if (ret < 0 )
287+ return ret ;
221288 lookup [i ] = eq ;
222- j += SOF_EQ_IIR_NHEADER
223- + SOF_EQ_IIR_NBIQUAD * eq -> num_sections ;
224289 } else {
225290 lookup [i ] = NULL ;
226291 }
@@ -318,7 +383,10 @@ int eq_iir_setup(struct processing_module *mod, int nch)
318383 /* Free existing IIR channels data if it was allocated */
319384 eq_iir_free_delaylines (mod );
320385
321- /* Set coefficients for each channel EQ from coefficient blob */
386+ /* Set coefficients for each channel EQ from coefficient blob.
387+ * eq_iir_init_coef() / eq_iir_blob_words_max() perform all blob size
388+ * sanity checks, including config->size vs cd->config_size.
389+ */
322390 delay_size = eq_iir_init_coef (mod , nch );
323391 if (delay_size < 0 )
324392 return delay_size ; /* Contains error code */
0 commit comments