Outmaster/tinygrad-gguf-cwe770-poc
tinygrad GGUF loader CWE-770 unbounded allocation PoC
Proof-of-concept file for a huntr Model Format Vulnerability report against tinygrad/tinygrad (GGUF loader).
evil.gguf is a 32-byte file: GGUF magic + version=3 + ntensors=0 + nkv=1, followed by a single KV-key length field (uint64) set to 1000000000000 (1TB), with no data bytes following.
read_str() (tinygrad/llm/gguf.py:121) reads this uint64 length prefix directly from the file and immediately calls r.read(read_uint64(r)) - no upper bound and no check against the stream's remaining byte count anywhere in the file. read_str is used for every GGUF KV-metadata key and every tensor name, so a single crafted file with one KV entry triggers the bug via its very first key.
Verified live on a fresh clone (commit c9e11544df5db55c13f06d01fba5300dd44332fb, 2026-07-28) under a 1.2GB RLIMIT_AS process cap:
import resource
resource.setrlimit(resource.RLIMIT_AS, (1_200_000_000, 1_200_000_000))
from tinygrad.llm.gguf import gguf_load
gguf_load("evil.gguf") # raises MemoryError from a 32-byte inputReachable via the public, documented loading API (gguf_load(Tensor(pathlib.Path(fn)))), used by tinygrad/llm/cli.py to load GGUF models from an arbitrary file/URL path, not only a preset dictionary.
Impact: Denial of Service - an attacker who can supply or influence a GGUF model file can force unbounded memory allocation from a file as small as 32 bytes.
