YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

llama.cpp / GGML β€” Unrecoverable Process Abort via Oversized Tensor Allocation (Reachable Assertion DoS)

Status: Preparing for Huntr submission Target: ggml-org/llama.cpp β€” native GGML/GGUF C/C++ loader (not the Python gguf-py bindings) File / function: ggml/src/ggml.c (ggml_init), reached via ggml/src/gguf.cpp (gguf_init_from_reader β†’ gguf_init_from_file) Class: CWE-617 (Reachable Assertion) Severity: Medium β€” a clean crash (no memory corruption), but on the real production model-loading path, unconditional, and uncatchable by any embedding application.

Summary

ggml_init() allocates its working memory buffer via ggml_aligned_malloc(mem_size), where mem_size is derived from a tensor's declared shape in a GGUF file. If the requested size is large enough that the allocation fails β€” which does not require any integer overflow, just an honestly large size that exceeds available system memory β€” the very next line fires an assertion:

struct ggml_context * ggml_init(struct ggml_init_params params) {
    ...
    *ctx = (struct ggml_context) {
        ...
        /*.mem_buffer = */ params.mem_buffer ? params.mem_buffer
                                               : ggml_aligned_malloc(mem_size),
        ...
    };
    GGML_ASSERT(ctx->mem_buffer != NULL);   // fires here on malloc failure

GGML_ASSERT calls ggml_abort(), which β€” confirmed by reading its source β€” calls the registered g_abort_callback if one exists, but unconditionally calls abort() immediately afterward regardless. There is no way for an embedding application to intercept or recover from this: no C++ exception is thrown, no error code is returned. The process terminates outright.

This is reached directly from the real model-loading call chain used by any application built on llama.cpp β€” server, CLI, or third-party integration β€” not example/demo code.

Proof of Concept

poc_ggml_oom_abort_dos.py hand-builds a minimal, 96-byte GGUF file (no dependency on any writer library): a single tensor declared with 500,000,000,000 float32 elements (~2 TB), zero KV metadata, zero real tensor data (the crash happens at allocation time, before any data would be read).

python3 poc_ggml_oom_abort_dos.py [path to a compiled llama-gguf binary]

Or manually, after building ggml-org/llama.cpp:

cmake -B build -DLLAMA_BUILD_EXAMPLES=ON
cmake --build build --target llama-gguf
./build/bin/llama-gguf minimal_alloc_crash.gguf r

Result

ggml_aligned_malloc: insufficient memory (attempted to allocate 1907348.63 MB)
ggml/src/ggml.c:1643: GGML_ASSERT(ctx->mem_buffer != NULL) failed
Aborted (exit code 134)

100% reproducible.

How this was found

Mutation fuzzing (500 trials, 1–6 random byte flips per trial on a legitimate ~13KB test GGUF file generated by llama.cpp's own examples/gguf/gguf.cpp writer) surfaced this crash, distinguishing real SIGSEGV/unusual SIGABRT outcomes from the many expected, gracefully-handled GGML_ASSERT-with-clear-error-message aborts that the parser correctly produces for most malformed input. The crash was then reduced to this clean, minimal, single-cause 96-byte reproduction.

The same fuzzing run also found an unrelated NULL pointer dereference (CWE-476) in examples/gguf/gguf.cpp:161, where the example/demo code calls gguf_get_version(ctx) without checking whether gguf_init_from_file() returned NULL. This second issue was confirmed to be demo-code-only: the real production loader (src/llama-model-loader.cpp:553-555) correctly checks if (metadata == nullptr) { throw std::runtime_error(...); }, so it does not affect any real inference pipeline. Not included as a primary finding here for that reason.

Relationship to other known issues in this area (included for transparency)

This exact function area (gguf_init_from_file_impl / mem_size computation / ggml_init) is under active, recent security research by multiple people:

  • An unrelated, already-published PoC for a division-by-zero in gguf.cpp line 623 (different mechanism: a zero-dimension tensor bypasses an off-by-one < 0 vs. <= 0 check).
  • A very recently reported issue describing a missing n_dims/GGML_MAX_DIMS bound check in the Python gguf-py bindings (distinct from this C++ finding and from this reporter's other gguf-py findings).
  • Most relevantly, an active GitHub Security Advisory, GHSA-3p4r-fq3f-q74v ("Heap Buffer Overflow via Integer Overflow in mem_size Calculation β€” Bypass of CVE-2025-53630 Fix"), in the same code region but a mechanistically distinct bug: that advisory involves an integer overflow that causes mem_size to wrap to a small value, so malloc succeeds with an undersized buffer, and a subsequent tensor-data write overflows it β€” genuine heap corruption, RCE-capable. This PoC's bug is the opposite failure mode: a large, non-overflowing size request that correctly fails to allocate, but whose failure path is an uncatchable process abort rather than a graceful, catchable error.

Given this, some triagers may treat a clean OOM-induced abort as lower priority than active memory-corruption issues, or possibly as intentional defensive behavior rather than a distinct vulnerability. It's included here regardless because an uncatchable crash on the production model-loading path of a widely embedded inference engine is a legitimate availability concern in its own right β€” e.g., a multi-tenant model-serving service that loads user-supplied GGUF files can be taken down entirely by a 96-byte file, with no way for the service to validate or reject the file gracefully first.

Suggested fix

Before calling ggml_aligned_malloc(mem_size) in ggml_init(), either validate mem_size against a configurable sane maximum and return an error through the normal gguf_init_from_file failure path (as is already done for other malformed-input cases), or have ggml_init() return NULL on allocation failure instead of asserting, letting callers handle it the same way they already handle other gguf_init_from_file failures.

Disclosure

ggml-org/llama.cpp's own private security disclosure program is currently disabled ("Emails will be ignored... submit patches as public PRs"), so this is being reported via Huntr (GGML is a listed $1500 bounty target). Please do not use this PoC against production systems you do not own or have explicit permission to test.

Downloads last month
10
GGUF
Hardware compatibility
Log In to add your hardware

We're not able to determine the quantization variants.

Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support