PoC β stable-diffusion.cpp GGUF tensor-dtype type confusion (OOB read + indirect call)
Proof-of-concept model file for a huntr Model File Vulnerabilities report against
leejet/stable-diffusion.cpp @ 3590aa8.
This repository contains a deliberately malformed GGUF file for authorized security research (responsible disclosure via huntr). It is not a usable model.
The bug (summary)
stable-diffusion.cpp ships its own lenient GGUF fallback parser (src/model_io/gguf_reader_ext.h)
used whenever the official ggml parser rejects a file. An attacker forces that fallback simply by
setting the GGUF version to an unsupported value (e.g. 1). The fallback then reads the per-tensor
type field (a uint32_t) and casts it to enum ggml_type with no range check β valid values
are 0..41. The out-of-range dtype is later used to index the fixed 42-element type_traits[] array
(ggml/src/ggml.c) in helpers guarded only by assert(), which is compiled out in the default
Release build. This yields:
- an out-of-bounds read during size math (
ggml_type_sizeinTensorStorage::nbytes()), and - the more serious primitive: in
convert_tensor()an out-of-bounds-readto_floatfunction pointer is indirectly CALLED (src/model_loader.cpp:178-183) β a CWE-822 untrusted-pointer indirect call / control-flow-hijack primitive.
Files
| file | description |
|---|---|
poc_gguf_wild_dtype.gguf |
65-byte malicious GGUF: version=1 (forces fallback) + one tensor with dtype enum 0x40000000. Deterministically crashes the default Release build with SIGSEGV. |
poc_gguf_type_confusion.gguf |
variant with dtype 42 (== GGML_TYPE_COUNT, first invalid index) for an ASan global-buffer-overflow demo. |
gen_gguf_type_confusion.py |
pure-python generator for both files. |
harness.cpp |
minimal harness that drives the real read_gguf_file() + nbytes() path. |
CRASH_PROVEN.md |
full build commands + reproduced crash (lldb stop frame). |
Reproduce
# build sd.cpp library (default Release, asserts stripped; NO sanitizer)
cmake -B build-rel -DCMAKE_BUILD_TYPE=Release -DGGML_METAL=OFF -DGGML_ACCELERATE=OFF -DGGML_BLAS=OFF -DSD_METAL=OFF -DGGML_NATIVE=OFF
cmake --build build-rel --target stable-diffusion
clang++ -std=c++17 -g -O1 -I src -I ggml/include harness.cpp \
build-rel/libstable-diffusion.a build-rel/ggml/src/libggml.a \
build-rel/ggml/src/libggml-cpu.a build-rel/ggml/src/libggml-base.a -o harness_rel
./harness_rel poc_gguf_wild_dtype.gguf # -> EXC_BAD_ACCESS in ggml_type_size (type_traits[] OOB)
Observed: read_gguf_file accepts the file (fallback), then SIGSEGV reading type_traits[0x40000000].
See CRASH_PROVEN.md.
Disclosure
Reported privately to the maintainer via huntr. Suggested fix: reject tensor type outside
[0, GGML_TYPE_COUNT) in the fallback parser (mirroring the official parser's existing check).
- Downloads last month
- 69
We're not able to determine the quantization variants.