A defender briefing for security leaders and AI platform teams: how a crafted GGUF model file reaches code execution through llama.cpp, which local LLM apps bundle the vulnerable parser, and the inventory and patch checklist that closes the gap.
A malicious model file can run code on the machine that loads it. In March 2026, the maintainers of llama.cpp published an advisory for CVE-2026-27940, a heap buffer overflow rated CVSS 7.8 in the function that parses GGUF model files, gguf_init_from_file_impl() in ggml/src/gguf.cpp. A crafted file triggers an integer overflow in the size math for the model context, the loader allocates a buffer far smaller than the tensor data requires, and a subsequent read writes attacker-controlled bytes past that buffer. The advisory demonstrates the overflow escalating to remote code execution, and it is fixed in build b8146 (GitHub Security Advisory GHSA-3p4r-fq3f-q74v; NVD, 2026).
Here is the direct answer to the question most teams running local AI are now asking. Can a malicious GGUF model file execute code on your machine when you run a local LLM like Ollama or llama.cpp? Yes, on an unpatched build. The 2026 GGUF parser flaws are not theoretical hardening notes: CVE-2026-27940 was demonstrated reaching code execution, and it is a bypass of an earlier 2025 flaw whose fix was incomplete (NVD, 2026). The exploit path is local, and it requires you to load the file, so the defense is not exotic. Pin a patched build, treat model files you did not produce as untrusted binaries, and sandbox the process that parses them.
This post is a defender walkthrough of the flaws, the local-AI products that inherit them, and the inventory and patch checklist to act on today. It stays at briefing depth on root cause: no crafted-file recipe, no proof of concept, no payload. For the broader agentic and model-layer attack surface, see our field guide on AI red teaming for LLM and agentic apps; this one stays on the model file and the loader that parses it.
The short answer: can a GGUF file run code on your machine?
Yes, if the code that opens it is unpatched. A GGUF file is not a passive blob of weights. It is a structured container with a header, key-value metadata, and tensor descriptors, and something has to parse all of that before a single token is generated. That parser is C and C++ code doing pointer arithmetic and heap allocation against numbers that come straight out of the file. When the file lies about those numbers, the parser can be steered into allocating too little memory and then writing too much.
That is exactly what CVE-2026-27940 does. The advisory notes that the memory size for the ggml context is computed without a combined overflow check, so individual additions are validated but their total is not (GHSA-3p4r-fq3f-q74v). Wrap that total and the allocation shrinks, while the amount of data read from the file does not, so the read runs off the end of the buffer with attacker-controlled bytes. The NVD entry states it plainly: the loader "is vulnerable to an Integer overflow, leading to an undersized heap allocation," and the subsequent read "writes 528+ bytes of attacker-controlled data past the buffer boundary" (NVD, 2026).
The CVSS vector, AV:L/AC:L/PR:N/UI:R, tells defenders how to think about it: the attack is local and needs user interaction, where the "interaction" is the act of loading the model. Nobody has to breach your network first. They have to get you to open a file. That is the same trust decision you already make about executables, installers, and browser downloads, applied to a file type many teams have been treating as inert data.
What GGUF is, and why the parser is the weak point
GGUF is the single-file format that packages a model's weights, tokenizer, and metadata for the llama.cpp inference stack, and it has become the de facto distribution format for open-weight models you run locally (GGUF format overview). The convenience is real: one file, portable across CPU and GPU backends, easy to share. The security consequence is that a single file now carries both data and the structural instructions that tell native code how to lay that data out in memory.
The parser lives in ggml, the tensor library underneath llama.cpp, in two places that both produced 2026 CVEs: gguf_init_from_file_impl() in ggml/src/gguf.cpp, which reads the container, and ggml_nbytes() in ggml/src/ggml.c, which computes how many bytes a tensor occupies. Both take attacker-influenced integers and turn them into allocation sizes. Both had overflow gaps. This is the classic memory-safety trap: untrusted length fields multiplied and added into a size that silently wraps, so a hostile file can describe a tensor that "fits" in a few megabytes on paper while actually demanding far more, and the write that follows lands wherever the undersized buffer ends.
The takeaway for defenders is structural, not incidental. Any format parsed by native code before validation is an attack surface, and model files are no exception. A GGUF file from an unknown source deserves the same suspicion as an unsigned binary from an unknown source, because on a vulnerable build it can have the same effect.
The 2026 llama.cpp parser CVEs
Three related advisories define the current picture. Two are 2026 flaws in the GGUF and tensor path, and the third is the 2025 flaw that the first one bypasses. The version and patch matrix below is the part to screenshot for your patch ticket.

CVE | Root cause | Location | CVSS | Fixed in |
|---|---|---|---|---|
CVE-2026-27940 | Integer overflow to undersized heap allocation, demonstrated reaching code execution |
| 7.8 High (3.1) | llama.cpp build b8146 |
CVE-2026-33298 | Tensor-size integer overflow, heap buffer overflow |
| 7.8 High (3.1) | llama.cpp build b7824 |
CVE-2025-53630 | Integer overflow to heap out-of-bounds read and write |
| 8.9 High (4.0) | mid-2025 fix commit |
Build b8146 is a later build than b7824, so pinning llama.cpp to b8146 or newer clears all three flaws in one move. That is the single number to put in your patch policy.
CVE-2026-27940: integer overflow to heap overflow in the GGUF loader
This is the headline flaw. Published on March 12, 2026, it sits in the same function as the 2025 issue and reaches the same class of memory corruption, but through a size computation the earlier fix did not cover. The NVD description is explicit that it "is a bypass of a similar bug in the same file, CVE-2025-53630, but the fix overlooked some areas," and that it "is fixed in b8146" (NVD, 2026). It carries two weakness classes, CWE-190 (integer overflow or wraparound) and CWE-122 (heap-based buffer overflow), which is the exact chain: a wrap in the size math feeds an undersized heap allocation, and the write past it is the overflow. The advisory shows the corruption escalating to code execution, which is why this one is not a stability bug you can defer.
CVE-2026-33298: tensor-size integer overflow in ggml_nbytes
The second 2026 flaw lives one layer over, in ggml_nbytes(), the routine that answers "how big is this tensor." Published in March 2026 (NVD dated 23 March 2026), it lets a crafted file with specific tensor dimensions make the function "return a significantly smaller size than required (e.g., 4MB instead of Exabytes), leading to a heap-based buffer overflow when the application subsequently processes the tensor" (NVD, 2026; GHSA-96jg-mvhq-q7q7). It is fixed in build b7824. The pattern is identical to the loader flaw: an untrusted dimension wraps a size calculation, and the code downstream trusts the wrong number.
The pattern: CVE-2025-53630 and why one fix was not enough
The 2025 flaw, CVE-2025-53630, was disclosed in July 2025 and described as an "Integer Overflow in the gguf_init_from_file_impl function in ggml/src/gguf.cpp" that "can lead to Heap Out-of-Bounds Read/Write," scored CVSS 4.0 at 8.9 (NVD, 2025). The fix landed, but it hardened only some of the size math, which is why CVE-2026-27940 could walk back in through an addition the patch did not guard. This is the important lesson for anyone tracking model-format security: a parser this size accretes overflow bugs, one fix rarely closes the whole class, and community disclosure keeps surfacing more of the GGUF validation gaps (oss-sec, 2026). Point-in-time patching is necessary but not sufficient. You need a process that keeps re-checking the build you actually run.
Who is exposed: the local-AI apps that bundle the parser
The reason a single parser flaw matters so much is that llama.cpp and ggml are not one product. They are the inference engine embedded inside most of the local-AI ecosystem, so the same gguf.cpp and ggml.c code paths ship inside tools that never say "llama.cpp" in their marketing.

llama.cpp itself, run directly as a CLI or server, parses GGUF through the affected functions (ggml-org/llama.cpp).
Ollama runs GGUF models and has historically vendored llama.cpp's ggml as its inference backend, so its model loading path inherits the parser (Ollama).
LM Studio is built on llama.cpp and ships a selectable llama.cpp runtime to execute GGUF models (LM Studio docs).
Jan uses a llama.cpp extension as its primary local inference engine for GGUF models (Jan local engine docs).
The practical consequence: knowing you patched "llama.cpp" is not the same as knowing your fleet is safe. Each of these tools bundles its own copy of the engine and updates it on its own schedule. A workstation running an old LM Studio, a CI job pulling a pinned Ollama image, and a developer's hand-built llama.cpp can each be on a different, and potentially vulnerable, build. Inventory has to reach the bundled engine version inside each app, not just the app version on the label.
Are you vulnerable? The inventory and patch checklist
Treat this as a short, concrete runbook. The goal is to know which build of the parser each tool is running, get everything to the patched floor, and reduce the blast radius of loading a file you do not fully trust.
Find the patch floor and pin it. For direct llama.cpp, the safe floor is build b8146 or later, which covers CVE-2026-27940, CVE-2026-33298, and the 2025 CVE-2025-53630 in one step. Pin that build in your Dockerfiles, package manifests, and provisioning scripts rather than tracking a floating "latest."
Inventory the bundled engine, not just the app. For Ollama, LM Studio, and Jan, identify the llama.cpp or ggml build each version ships, because the app's own version number does not tell you the parser version. Where a tool does not expose that build, update the tool to its latest release and confirm the vendor has picked up a llama.cpp build at or above the floor.
Treat every model file you did not build as untrusted input. A GGUF file downloaded from a public hub, a forum, a shared drive, or a teammate is external code input to a native parser. Apply the same gate you use for binaries: prefer trusted publishers, verify checksums against the publisher's stated hash, and quarantine anything unverified.
Sandbox model loading. Load and parse models in a constrained process: a container or VM with no network egress, a non-privileged user, a read-only filesystem where possible, and syscall or capability restrictions. If a parser flaw does fire, a sandbox is the difference between a crashed loader and a compromised host.
Separate untrusted parsing from privileged work. Do not parse arbitrary community models in the same process or host that holds production credentials, signing keys, or customer data. Keep model intake on isolated infrastructure and promote only verified files inward.
Make it continuous. Model-format CVEs have landed repeatedly across 2025 and 2026 in the same files, so a single patch pass ages quickly. Add the bundled engine build to your vulnerability management scope and re-check it on a schedule and after every tool update.
Why untrusted model files are untrusted binaries
The mental model shift is the whole point. For years the industry treated model weights as data and executables as code, and hardened only the second category. GGUF collapses that distinction. The file carries structural fields that native code interprets before any safety checks, and on a vulnerable build those fields decide how memory is allocated and written. A file that can steer a heap allocation is, functionally, code.
That is why "I only run local models, so I am not exposed to the internet" is the wrong frame. The exposure is not a listening port. It is the supply chain of files you feed the parser: the model you pulled to save API costs, the fine-tune a vendor shipped, the quantized variant a community member uploaded. Any of those is a delivery vehicle on an unpatched build. The controls that work are the ones you already trust for software supply chain, applied to model artifacts: provenance, integrity verification, least privilege, and sandboxing. Converting or quantizing a file does not sanitize it either, because the malicious values live in the structure the parser reads, not in the weights you are re-encoding.
Where Stingrai fits
AI supply-chain security has to include the model files themselves and the loaders that parse them, and that is offensive-security work our senior human pentesters own. Stingrai is a CREST-accredited firm, founded in 2021, that tests AI-powered products across their real attack surface, and model-file provenance and parser handling sit squarely inside an ML supply-chain assessment. Our human-led testing examines how a product ingests untrusted model artifacts, whether it pins and verifies the inference engine it bundles, and whether parsing is isolated from privileged data, mapped to the failure classes these GGUF CVEs represent. That is the same discipline behind our red teaming and adversary-emulation practice, extended to the model layer, and it pairs naturally with our work on the RAG and vector-store access-control layer and the MCP connectors around the same products.
The web application and API that wrap a local-AI product still need conventional testing, and that is where our autonomous agent Snipe operates. Snipe runs web application penetration testing on the app around the model, purpose-built to hunt the complex classes generic scanners miss: IDOR, broken authorization, and business logic flaws. Snipe covers the web-app layer; senior pentesters cover the model-file and inference-engine layer. Both feed the same PTaaS program, so findings are tracked, retested, and continuous rather than a one-off report. Because model-format CVEs land continuously in the same parser files, a point-in-time scan goes stale within a release cycle, which is exactly the gap continuous validation closes. This testing also produces the evidence a secure-SDLC program and a SOC 2 or ISO 27001 audit expect: an independent offensive-security team exercising a privileged input path, with findings and remediation you can show an assessor. Scope and packaging are on our pricing page, and the full services overview covers where model-layer testing fits.
What this means for security leaders
Pin the patched build now. Set llama.cpp build b8146 or later as the floor across every place the engine runs, directly or bundled, and close CVE-2026-27940, CVE-2026-33298, and CVE-2025-53630 in one move.
Inventory the engine inside the app. Ollama, LM Studio, and Jan each carry their own llama.cpp or ggml build; track that build, not just the product version, or your patch report will lie to you.
Gate model files like binaries. Provenance, checksum verification, and trusted publishers apply to GGUF the same way they apply to executables, because on a vulnerable build a model file has the same reach.
Sandbox and isolate parsing. Load untrusted models in a constrained, network-isolated process away from production secrets, so a parser flaw is contained rather than catastrophic.
Make model-layer testing continuous. These CVEs keep recurring in the same files, so fold the bundled engine build into continuous validation and retest after every material change instead of trusting a single pass.
Frequently Asked Questions
Can a malicious GGUF model file execute code on my machine when I run a local LLM like Ollama or llama.cpp?
Yes, on an unpatched build. CVE-2026-27940, a CVSS 7.8 flaw published in March 2026, lets a crafted GGUF file trigger an integer overflow in llama.cpp's GGUF loader that produces an undersized heap allocation, and the advisory demonstrates the resulting overflow reaching remote code execution (NVD, 2026). The attack is local and requires you to load the file, so the defense is to pin a patched build (llama.cpp b8146 or later), treat untrusted model files like untrusted binaries, and sandbox model loading.
What is CVE-2026-27940?
CVE-2026-27940 is a heap buffer overflow, rated CVSS 7.8, in the GGUF parser function gguf_init_from_file_impl() in ggml/src/gguf.cpp. A crafted file wraps the model context size computation, the loader allocates a buffer smaller than the tensor data needs, and a following read writes attacker-controlled bytes past it. It is fixed in llama.cpp build b8146 and is explicitly a bypass of the earlier CVE-2025-53630 (GHSA-3p4r-fq3f-q74v).
Is my llama.cpp vulnerable, and how do I check?
You are exposed if you run a build earlier than b8146 for direct llama.cpp. Check the build tag your binary or container image reports and compare it to the b8146 floor, which covers both 2026 CVEs and the 2025 one. If you run a bundled tool such as Ollama, LM Studio, or Jan, check the llama.cpp or ggml build that tool ships rather than the app version, because the two are not the same number.
Which local LLM apps are affected?
Any tool that parses GGUF through llama.cpp or ggml. That includes llama.cpp run directly, plus Ollama, LM Studio, and Jan, which all bundle a llama.cpp or ggml inference engine to run GGUF models (Jan docs; LM Studio docs). Each ships its own copy of the engine on its own update cadence, so they can be on different builds and different exposure levels at the same time.
What is the difference between CVE-2026-27940 and CVE-2025-53630?
They are the same class of bug in the same function, gguf_init_from_file_impl(), but CVE-2026-27940 is a bypass of the fix for CVE-2025-53630. The 2025 fix hardened part of the size math, and the 2026 flaw reaches the same heap corruption through an addition the patch did not guard (NVD, 2026). Build b8146 fixes the bypass; the 2025 flaw was fixed in mid-2025.
What is CVE-2026-33298?
CVE-2026-33298 is a CVSS 7.8 integer overflow in ggml_nbytes() in ggml/src/ggml.c, the function that computes a tensor's size. A crafted file with specific tensor dimensions makes it return a size far smaller than required, leading to a heap-based buffer overflow when the tensor is processed. It is fixed in llama.cpp build b7824 (NVD, 2026).
Do I need to worry if I only download models from Hugging Face or another reputable hub?
Reputable hubs lower the odds but do not remove the risk, because files can be re-uploaded, forked, or tampered with, and integrity still depends on you verifying the publisher and checksum. Treat provenance and checksum verification as required steps and keep untrusted files off privileged hosts. The parser flaw fires on the file's structure, so a trusted-looking name is not a safety guarantee on a vulnerable build.
How should I sandbox local model loading?
Parse and load models in a constrained process: a container or VM with no network egress, a non-privileged user, a read-only filesystem where practical, and syscall or capability restrictions. Keep that process away from production credentials and customer data. If a parser flaw does trigger, this containment is what turns a host compromise into a contained crash.
Does converting or quantizing a model make it safe?
No. The malicious values that drive these overflows live in the structural fields a parser reads, not in the weights you re-encode, so converting or quantizing a hostile file does not sanitize it and can require parsing it on a vulnerable build in the first place. Verify provenance before you process a file, and do the processing in a sandbox.
Does Stingrai's Snipe test model-file parsers?
No. Snipe is Stingrai's autonomous agent for web application penetration testing, and it covers the web-app and API layer of an AI product, hunting complex classes such as IDOR, broken authorization, and business logic flaws. Model-file provenance and the inference-engine parser are ML supply-chain testing, handled by Stingrai's senior human pentesters and human-led AI red team.
References
GitHub Security Advisory (ggml-org/llama.cpp). GHSA-3p4r-fq3f-q74v: Integer overflow in gguf_init_from_file_impl leading to heap overflow. March 12, 2026. https://github.com/ggml-org/llama.cpp/security/advisories/GHSA-3p4r-fq3f-q74v. Maintainer advisory for CVE-2026-27940, describing the missing combined overflow check on the ggml context size and the fix in build b8146.
NIST National Vulnerability Database. CVE-2026-27940. Published March 12, 2026. https://nvd.nist.gov/vuln/detail/CVE-2026-27940. CVSS 7.8 heap buffer overflow (CWE-190, CWE-122) in the GGUF loader, a bypass of CVE-2025-53630, fixed in b8146.
NIST National Vulnerability Database. CVE-2026-33298. Published March 23, 2026. https://nvd.nist.gov/vuln/detail/CVE-2026-33298. CVSS 7.8 integer overflow in ggml_nbytes returning an undersized tensor size, leading to a heap overflow, fixed in b7824.
GitHub Security Advisory (ggml-org/llama.cpp). GHSA-96jg-mvhq-q7q7: Heap overflow via integer overflow in ggml_nbytes. March 2026. https://github.com/ggml-org/llama.cpp/security/advisories/GHSA-96jg-mvhq-q7q7. Maintainer advisory for CVE-2026-33298, with the patched build b7824.
NIST National Vulnerability Database. CVE-2025-53630. Published July 10, 2025. https://nvd.nist.gov/vuln/detail/CVE-2025-53630. CVSS 4.0 score 8.9 integer overflow in gguf_init_from_file_impl leading to heap out-of-bounds read and write; the prior flaw that CVE-2026-27940 bypasses.
oss-sec mailing list. GGUF parser validation disclosure thread. 2026. https://seclists.org/oss-sec/2026/q2/546. Community disclosure discussing validation gaps in the GGUF parser implementation.
ggml-org. llama.cpp. https://github.com/ggml-org/llama.cpp. The C and C++ inference engine and ggml tensor library that host the GGUF parser and are bundled across the local-AI ecosystem.
Menlo Research. Jan: Local AI Engine (llama.cpp). https://www.jan.ai/docs/desktop/local-engine/llama-cpp. Documentation confirming Jan uses a llama.cpp extension as its primary local inference engine for GGUF models.
LM Studio. LM Studio documentation. https://lmstudio.ai/docs/app. Product documentation for the desktop app that runs GGUF models on a bundled llama.cpp runtime.
Ollama. Ollama. https://github.com/ollama/ollama. Local model runner that executes GGUF models and has historically vendored llama.cpp's ggml as its inference backend.


