Summary
A SEGV (null/wild pointer dereference) occurs in whisper_free_state() at src/whisper.cpp:3824 when error cleanup frees an uninitialized whisper_batch structure. When whisper_init_state() fails during KV cache initialization, whisper_batch fields contain uninitialized memory, and the subsequent whisper_batch_free() call attempts to free wild pointers.
CWE-824 (Access of Uninitialized Pointer), CVSS 6.5 (Medium).
Tested version
- Commit:
fc67457 (current master HEAD, 2026-04-20)
- Build: cmake with
-fsanitize=address,undefined -fno-omit-frame-pointer -g
- Platform: Ubuntu 22.04 x86_64, GCC 11
Root cause
In whisper_init_state(), whisper_batch is allocated as part of whisper_state but not zero-initialized before error paths that call cleanup:
// whisper.cpp:3392 (error path in whisper_init_state)
whisper_free_state(state); // state->batch contains uninitialized memory
// whisper.cpp:3824 (in whisper_free_state)
whisper_batch_free(state->batch); // frees wild pointers
// whisper.cpp:499 (in whisper_batch_free)
free(batch.token); // wild pointer → SEGV
When kv_cache_init() fails (e.g., due to corrupted model parameters), the error cleanup path calls whisper_free_state(), which tries to free state->batch.token — a pointer that was never initialized.
ASAN output
==3137759==ERROR: AddressSanitizer: SEGV on unknown address
The signal is caused by a READ memory access.
Hint: this fault was caused by a dereference of a high value address.
#0 in __asan::Allocator::Deallocate
#1 in __interceptor_free
#2 in whisper_batch_free(whisper_batch) whisper.cpp:499
#3 in whisper_free_state whisper.cpp:3824
#4 in whisper_init_state whisper.cpp:3392
#5 in whisper_init_from_file_with_params whisper.cpp:3741
Suggested fix
Zero-initialize whisper_batch before any error path can trigger cleanup:
// In whisper_init_state(), after allocating state:
state->batch = {}; // or memset(&state->batch, 0, sizeof(state->batch));
Or add a null check in whisper_batch_free():
void whisper_batch_free(struct whisper_batch batch) {
if (batch.token) free(batch.token);
if (batch.embd) free(batch.embd);
// ...
}
Impact
- Denial of Service: Crafted model file crashes any application using whisper.cpp model loading
- Potential UAF: If the uninitialized pointer happens to point to a valid-but-freed heap region, this becomes a use-after-free with potential code execution impact
Disclosure
These vulnerabilities were found via generative fuzzing with a custom harness. The report was polished with AI assistance.
PoC file will be provided via gist link in comment below.
Summary
A SEGV (null/wild pointer dereference) occurs in
whisper_free_state()atsrc/whisper.cpp:3824when error cleanup frees an uninitializedwhisper_batchstructure. Whenwhisper_init_state()fails during KV cache initialization,whisper_batchfields contain uninitialized memory, and the subsequentwhisper_batch_free()call attempts to free wild pointers.CWE-824 (Access of Uninitialized Pointer), CVSS 6.5 (Medium).
Tested version
fc67457(currentmasterHEAD, 2026-04-20)-fsanitize=address,undefined -fno-omit-frame-pointer -gRoot cause
In
whisper_init_state(),whisper_batchis allocated as part ofwhisper_statebut not zero-initialized before error paths that call cleanup:When
kv_cache_init()fails (e.g., due to corrupted model parameters), the error cleanup path callswhisper_free_state(), which tries to freestate->batch.token— a pointer that was never initialized.ASAN output
Suggested fix
Zero-initialize
whisper_batchbefore any error path can trigger cleanup:Or add a null check in
whisper_batch_free():Impact
Disclosure
These vulnerabilities were found via generative fuzzing with a custom harness. The report was polished with AI assistance.
PoC file will be provided via gist link in comment below.