Skip to content

Commit dbdd503

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 dbdd503

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

src/include/sof/math/auditory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sof/math/log.h>
1515
#include <stdint.h>
1616

17+
#define AUDITORY_MAX_MEL_BANDS 256
1718
#define AUDITORY_EPS_Q31 1 /* Smallest nonzero Q1.31 value */
1819
#define AUDITORY_LOG2_2P25_Q16 Q_CONVERT_FLOAT(25.0, 16) /* log2(2^25) */
1920

src/math/auditory/auditory.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
#include <sof/math/fft.h>
1313
#include <sof/math/log.h>
1414
#include <sof/math/numbers.h>
15+
#include <sof/trace/trace.h>
1516
#include <ipc/topology.h>
1617
#include <errno.h>
1718
#include <stdint.h>
1819

20+
LOG_MODULE_REGISTER(math_auditory, CONFIG_SOF_LOG_LEVEL);
21+
1922
#define ONE_Q16 Q_CONVERT_FLOAT(1, 16)
2023
#define ONE_Q20 Q_CONVERT_FLOAT(1, 20)
2124
#define ONE_Q30 Q_CONVERT_FLOAT(1, 30)
@@ -117,6 +120,16 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil
117120
if (!fb->scratch_data1 || !fb->scratch_data2)
118121
return -ENOMEM;
119122

123+
/* fb->mel_bins is used both as the loop bound and as part of the
124+
* (mel_bins + 1) divisor below. Reject non-positive values up front to
125+
* avoid a divide by zero (mel_bins == -1) and to keep mel_step
126+
* meaningful.
127+
*/
128+
if (fb->mel_bins <= 0 || fb->mel_bins > AUDITORY_MAX_MEL_BANDS) {
129+
comp_cl_err(mod->dev, "Invalid mel_bins %d", fb->mel_bins);
130+
return -EINVAL;
131+
}
132+
120133
/* Log power can be log, or log10 or dB, get multiply coef to convert
121134
* log to desired format.
122135
*/
@@ -149,6 +162,17 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil
149162
mel_start = psy_hz_to_mel(fb->start_freq);
150163
mel_end = psy_hz_to_mel(fb->end_freq);
151164
mel_step = (mel_end - mel_start) / (fb->mel_bins + 1);
165+
/* delta_cl / delta_rc below are both equal to mel_step; guard against
166+
* a non-positive step (start_freq >= end_freq, or so many bins that
167+
* the integer division truncates to zero) before using them as
168+
* divisors.
169+
*/
170+
if (mel_step <= 0) {
171+
comp_cl_err(mod->dev, "Invalid mel_step %d (start_freq=%d end_freq=%d mel_bins=%d)",
172+
mel_step, fb->start_freq, fb->end_freq, fb->mel_bins);
173+
return -EINVAL;
174+
}
175+
152176
for (i = 0; i < fb->mel_bins; i++) {
153177
left_mel = mel_start + i * mel_step;
154178
center_mel = mel_start + (i + 1) * mel_step;
@@ -160,6 +184,11 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil
160184
if (fb->slaney_normalize) {
161185
left_hz = psy_mel_to_hz(left_mel);
162186
right_hz = psy_mel_to_hz(right_mel);
187+
if (right_hz <= left_hz) {
188+
comp_cl_err(mod->dev, "Invalid Hz range left=%d right=%d at mel bin %d",
189+
left_hz, right_hz, i);
190+
return -EINVAL;
191+
}
163192
scale = Q_SHIFT_RND(TWO_Q29 / (right_hz - left_hz), 29, 16); /* Q16.16*/
164193
if (i == 0) {
165194
scale_inv = Q_SHIFT_LEFT(ONE_Q30 / scale, 14, 16);

0 commit comments

Comments
 (0)