You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

Uncontrolled Memory Allocation via Unchecked n_mel * n_fft Mel-Filter Header Fields in whisper.cpp's Legacy GGML Model Loader

Gated PoC repository for a huntr Model File Vulnerability submission. Access is granted on request (e.g. to protectai-bot for triage).

Target format: GGML (.ggml) – llama.cpp / ggml-org ecosystem (huntr target id ggml) Project: ggml-org/whisper.cpp Affected commit: 6fc7c33b4c3a2cec83e4b65abd5e96a890480375 (2026-07-01, current master at time of testing) Affected location: whisper_model_load() β€” src/whisper.cpp:1576-1586; identical pattern in parakeet_model_load() β€” src/parakeet.cpp:1058-1067.

Summary

Immediately after the hparams block, whisper.cpp reads two attacker-controlled 32-bit fields and uses their product, completely unchecked, to size a std::vector<float>:

auto & filters = wctx.model.filters;
read_safe(loader, filters.n_mel);
read_safe(loader, filters.n_fft);

filters.data.resize(filters.n_mel * filters.n_fft);
loader->read(loader->context, filters.data.data(), filters.data.size() * sizeof(float));

(src/whisper.cpp:1580-1584; struct whisper_filters { int32_t n_mel; int32_t n_fft; std::vector<float> data; }; at src/whisper.cpp:422-427)

There is no upper bound on n_mel or n_fft (both attacker-controlled int32_t read straight from the file), and no plausibility check against the actual mel-filter sizes whisper.cpp ever legitimately uses (80 or 128 for real Whisper models). A crafted file with implausible-but-small header values (e.g. n_mel = 130048, n_fft = 65536, encoded in just 8 bytes) drives a resize() request of n_mel * n_fft * sizeof(float) β‰ˆ 34 GB from a total input file of under 100 bytes.

This is a classic amplification / uncontrolled-resource-consumption bug (CWE-789): a tiny attacker-supplied file forces a multi-gigabyte allocation attempt before any real model data has even been validated, well before the point where an application could reasonably decide "this doesn't look like a real model." On memory-constrained deployments (containers, shared hosts, serverless inference endpoints β€” common whisper.cpp deployment targets) this reliably invokes the OOM killer or otherwise denies service, and is trivially repeatable (near-zero attacker cost per attempt vs. multi-GB victim-side allocation attempt).

Reachable via the same public, documented API as the other findings in this series:

whisper_context * ctx = whisper_init_from_file_with_params_no_state(path, whisper_context_default_params());

Proof of Concept

Found independently via a 30-minute AFL++ coverage-guided fuzzing campaign (afl-clang-fast++ -fsanitize=address, seeded from a minimal valid header) against a harness calling the real public loading API β€” not hand-constructed. File: afl_found_crash_oom_mel_filters.bin (78 bytes).

Decoded header fields (from the crashing file): n_audio_layer=4 (valid, MODEL_TINY), n_mel = 130048, n_fft = 65536 β†’ requested allocation = 130048 Γ— 65536 Γ— 4 bytes = 34,091,302,912 bytes (~34.1 GB), confirmed by the ASan trace as the exact byte count operator new was asked for β€” i.e. this is the literal, non-overflowed mathematical product of two small header ints, not a SIZE_MAX/wraparound artifact. It would fail identically (via std::bad_alloc, uncaught, SIGABRT) on any real deployment target without terabytes of free memory, so this is not an ASan-allocator-ceiling artifact β€” it reproduces the same way with or without AddressSanitizer.

asan_trace: afl_found_asan_trace_oom.txt:

==...==ERROR: AddressSanitizer: out of memory: allocator is trying to allocate 0x7f0000000 bytes
    #0 ... in operator new(unsigned long)
    #1 ... in std::__new_allocator<float>::allocate(...)
    #2 ... in std::allocator_traits<std::allocator<float>>::allocate(...)
    #3 ... in std::_Vector_base<float, std::allocator<float>>::_M_allocate(...)
    #4 ... in std::vector<float, std::allocator<float>>::_M_default_append(...)
==...==ABORTING

(0x7f0000000 = 34,091,302,912 = 130048 Γ— 65536 Γ— 4, confirming the trace matches filters.data.resize(filters.n_mel * filters.n_fft) exactly β€” this is the only single-argument vector<float>::resize() call in the loading path.)

harness_whisper.cpp β€” identical harness used for the sibling n_dims finding in this series, calling whisper_init_from_file_with_params_no_state() directly.

Impact

Denial of service via a sub-100-byte crafted file forcing a tens-of-gigabytes allocation attempt during model loading, before any real validation of the file's legitimacy. Same underlying missing-bounds-check pattern (unchecked attacker int32 fields multiplied directly into an allocation size) recurs verbatim in parakeet_model_load() (src/parakeet.cpp:1065, filters.data.resize(filters.n_mel * filters.n_fb)), so this is reported as one root cause covering both call sites, not two.

Suggested fix

Validate n_mel and n_fft (and n_fb in parakeet.cpp) against sane upper bounds (e.g. a few thousand) β€” and/or against the file's actual remaining byte length β€” before calling resize(), in both whisper_model_load() and parakeet_model_load().

Dedup / novelty check

Searched GitHub issues, whisper.cpp's security advisories page, and CVE trackers for "mel filter", "n_mel n_fft allocation", "unbounded allocation whisper.cpp" β€” found only unrelated memory-usage discussions (e.g. issue #2310, about legitimate long-audio transcription using a lot of RAM at inference time, not malicious model-file headers at load time) and issue #3807 (a different root cause β€” zero-dimension hparams causing a null-deref/assert, not an oversized allocation). No prior disclosure of this specific n_mel/n_fft unbounded-allocation path was found.

Files in this repo

  • harness_whisper.cpp β€” harness calling the real public loading API
  • afl_found_crash_oom_mel_filters.bin β€” AFL++-discovered crashing input (not hand-crafted)
  • afl_found_asan_trace_oom.txt β€” full ASan trace
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support