Skip to content

Commit 4f88f36

Browse files
committed
math: auditory: guard mod_psy_get_mel_filterbank() against zero divisors
The mel-bin loop in mod_psy_get_mel_filterbank() divides by delta_cl and delta_rc on every FFT bin, and by (right_hz - left_hz) when slaney normalization is enabled. With unusual configurations these denominators can become zero or negative — for example when start_freq >= end_freq, when the requested mel_bins is large enough that integer division truncates the mel step to zero, or at extreme inputs where psy_mel_to_hz saturates and right_hz no longer exceeds left_hz. Reject such configurations explicitly. After computing mel_step, return -EINVAL if it is not positive, which also covers both delta values since they equal mel_step. In the slaney_normalize branch, also verify right_hz > left_hz before computing the scale factor. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 462cfb5 commit 4f88f36

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

src/math/auditory/auditory.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil
149149
mel_start = psy_hz_to_mel(fb->start_freq);
150150
mel_end = psy_hz_to_mel(fb->end_freq);
151151
mel_step = (mel_end - mel_start) / (fb->mel_bins + 1);
152+
/* delta_cl / delta_rc below are both equal to mel_step; guard against
153+
* a non-positive step (start_freq >= end_freq, or so few bins that the
154+
* integer division truncates to zero) before using them as divisors.
155+
*/
156+
if (mel_step <= 0) {
157+
comp_cl_err(mod->dev, "Invalid mel_step %d (start_freq=%d end_freq=%d mel_bins=%d)",
158+
mel_step, fb->start_freq, fb->end_freq, fb->mel_bins);
159+
return -EINVAL;
160+
}
161+
152162
for (i = 0; i < fb->mel_bins; i++) {
153163
left_mel = mel_start + i * mel_step;
154164
center_mel = mel_start + (i + 1) * mel_step;
@@ -160,6 +170,11 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil
160170
if (fb->slaney_normalize) {
161171
left_hz = psy_mel_to_hz(left_mel);
162172
right_hz = psy_mel_to_hz(right_mel);
173+
if (right_hz <= left_hz) {
174+
comp_cl_err(mod->dev, "Invalid Hz range left=%d right=%d at mel bin %d",
175+
left_hz, right_hz, i);
176+
return -EINVAL;
177+
}
163178
scale = Q_SHIFT_RND(TWO_Q29 / (right_hz - left_hz), 29, 16); /* Q16.16*/
164179
if (i == 0) {
165180
scale_inv = Q_SHIFT_LEFT(ONE_Q30 / scale, 14, 16);

0 commit comments

Comments
 (0)