From 8631825d41a2712268813981a9550b04a3f225e5 Mon Sep 17 00:00:00 2001 From: Md Shafiuzzaman Date: Thu, 6 Aug 2026 23:17:31 -0700 Subject: [PATCH] whisper : heap out-of-bounds read in log_mel_spectrogram on very short audio (#3956) log_mel_spectrogram reflect-pads the start of the audio buffer by reading 200 samples from samples[1], with no check that the input has that many samples. Audio shorter than 201 samples reads past the end of `samples` (heap out-of-bounds read); the existing minimum-length check runs later, in whisper_full_with_state, after this access. Clamp the reflected count to the available input. Normal-length audio (n_samples >= 201) is unchanged. --- src/whisper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/whisper.cpp b/src/whisper.cpp index 4ac3b1104..89146e2e4 100644 --- a/src/whisper.cpp +++ b/src/whisper.cpp @@ -3203,8 +3203,12 @@ static bool log_mel_spectrogram( // pad 30 seconds of zeros at the end of audio (480,000 samples) + reflective pad 200 samples at the end of audio std::fill(samples_padded.begin() + n_samples + stage_2_pad, samples_padded.begin() + n_samples + stage_1_pad + 2 * stage_2_pad, 0); - // reflective pad 200 samples at the beginning of audio - std::reverse_copy(samples + 1, samples + 1 + stage_2_pad, samples_padded.begin()); + // reflective pad up to 200 samples at the beginning of audio + // clamp the reflected count to the available input so very short audio (n_samples <= stage_2_pad) + // does not read past the end of `samples` + const int64_t n_reflect = std::min(stage_2_pad, std::max(0, (int64_t) n_samples - 1)); + std::reverse_copy(samples + 1, samples + 1 + n_reflect, samples_padded.begin() + (stage_2_pad - n_reflect)); + mel.n_mel = n_mel; // https://github.com/pytorch/pytorch/blob/main/aten/src/ATen/native/SpectralOps.cpp#L936