PoC: Denial of Service in gguf-py via unbounded metadata-array length (huntr MFV)
Security proof-of-concept β not a real model. model.gguf is a 49-byte malicious GGUF.
Loading it with the official gguf Python library (gguf-py, used by transformers, huggingface_hub, and many GGUF tools) hangs forever (infinite loop + unbounded memory growth). The reader applies no upper bound to the metadata array length, so a declared length of 2**63 with no backing data spins in place at EOF indefinitely.
Reproduce (β10 seconds)
pip install gguf
# WARNING: this hangs β run with a timeout so it doesn't lock your terminal:
timeout 10 python -c "from gguf.gguf_reader import GGUFReader; GGUFReader('model.gguf')"
echo "exit code: $? (124 = timed out = still parsing a 49-byte file = DoS)"
A well-formed GGUF parses in milliseconds; this 49-byte file never returns.
Root cause
gguf/gguf_reader.py β _get_field_parts(), ARRAY branch:
alen = self._get(offs, np.uint64) # attacker-controlled, UNBOUNDED
...
for idx in range(alen[0]): # range(2**63)
curr_size, curr_parts, ... = self._get_field_parts(offs, raw_itype[0])
aparts += curr_parts # grows every iteration
offs += curr_size # past EOF -> curr_size == 0 -> offs frozen -> infinite loop
Instrumentation confirms genuine non-termination (not slowness): the read offset stays pinned at EOF across ~700k reads in 5s (β2.1M years to finish 2**63 iterations), while the aparts list grows without bound.
Impact
Any tool that reads an untrusted GGUF's metadata with gguf-py (model loaders, metadata extractors, conversion/inspection pipelines) hangs and exhausts memory on a tiny crafted file.
Fix
Bound the array length (and kv_count, tensor_count, n_dims, string lengths) against the remaining file size before looping; abort if a read makes no forward progress.
- Downloads last month
- -
We're not able to determine the quantization variants.