Skip to content

Commit 031c1e0

Browse files
matejsmyckaclaude
andcommitted
osce: Clamp pitch embedding index to prevent OOB read
The LACE and NoLACE feature networks access the pitch embedding table using periods[i_subframe] as a direct index without bounds checking. SILK's decode_pitch() clamps pitch lags to [min_lag, max_lag] where max_lag = PE_MAX_LAG_MS * Fs_kHz = 288 at 16kHz. If a model is trained with pitch_max < 288 (the Python training defaults use pitch_max=257), pitch lag values in the range [pitch_max+1, 288] would read past the end of the embedding weight table. Add IMIN/IMAX clamping to bound the pitch index to [0, *_PITCH_MAX] before the embedding lookup, consistent with how FARGAN handles pitch embedding access in fargan.c:53. The current shipped model (v1.6.1) uses pitch_max=300 which covers the full SILK pitch range, but the C code should defensively clamp regardless of model parameters. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 788cc89 commit 031c1e0

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

dnn/osce.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ static void lace_feature_net(
183183
/* scaling and dimensionality reduction */
184184
for (i_subframe = 0; i_subframe < 4; i_subframe ++)
185185
{
186+
int pitch_index = IMAX(0, IMIN(periods[i_subframe], LACE_PITCH_MAX));
186187
OPUS_COPY(input_buffer, features + i_subframe * LACE_NUM_FEATURES, LACE_NUM_FEATURES);
187-
OPUS_COPY(input_buffer + LACE_NUM_FEATURES, hLACE->layers.lace_pitch_embedding.float_weights + periods[i_subframe] * LACE_PITCH_EMBEDDING_DIM, LACE_PITCH_EMBEDDING_DIM);
188+
OPUS_COPY(input_buffer + LACE_NUM_FEATURES, hLACE->layers.lace_pitch_embedding.float_weights + pitch_index * LACE_PITCH_EMBEDDING_DIM, LACE_PITCH_EMBEDDING_DIM);
188189
OPUS_COPY(input_buffer + LACE_NUM_FEATURES + LACE_PITCH_EMBEDDING_DIM, numbits_embedded, 2 * LACE_NUMBITS_EMBEDDING_DIM);
189190

190191
compute_generic_conv1d(
@@ -454,8 +455,9 @@ static void nolace_feature_net(
454455
/* scaling and dimensionality reduction */
455456
for (i_subframe = 0; i_subframe < 4; i_subframe ++)
456457
{
458+
int pitch_index = IMAX(0, IMIN(periods[i_subframe], NOLACE_PITCH_MAX));
457459
OPUS_COPY(input_buffer, features + i_subframe * NOLACE_NUM_FEATURES, NOLACE_NUM_FEATURES);
458-
OPUS_COPY(input_buffer + NOLACE_NUM_FEATURES, hNoLACE->layers.nolace_pitch_embedding.float_weights + periods[i_subframe] * NOLACE_PITCH_EMBEDDING_DIM, NOLACE_PITCH_EMBEDDING_DIM);
460+
OPUS_COPY(input_buffer + NOLACE_NUM_FEATURES, hNoLACE->layers.nolace_pitch_embedding.float_weights + pitch_index * NOLACE_PITCH_EMBEDDING_DIM, NOLACE_PITCH_EMBEDDING_DIM);
459461
OPUS_COPY(input_buffer + NOLACE_NUM_FEATURES + NOLACE_PITCH_EMBEDDING_DIM, numbits_embedded, 2 * NOLACE_NUMBITS_EMBEDDING_DIM);
460462

461463
compute_generic_conv1d(

0 commit comments

Comments
 (0)