ITADN

SEGV in whisper_free_state via uninitialized whisper_batch pointer

#3788Openqi-scape 创建于 2026-05-01
Q
qi-scapecommented
## 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: ```cpp // 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: ```cpp // 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()`: ```cpp 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.
1 条评论