CVE-2026-47747 Overview
CVE-2026-47747 is a heap buffer overflow [CWE-122] in stable-diffusion.cpp, a pure C/C++ inference library for diffusion models including Stable Diffusion, Flux, Wan, Qwen Image, and Z-Image. The flaw resides in the pickle .ckpt parser inside src/model.cpp, specifically in the BINUNICODE opcode handler. Sign confusion on the opcode length field allows a crafted .ckpt file to trigger memcpy with a length derived from a negative signed value, producing immediate heap corruption. The issue affects versions prior to master-584-0a7ae07 and is fixed in master-584-0a7ae07.
Critical Impact
A malicious .ckpt checkpoint file can corrupt heap memory during parsing, enabling local code execution in the context of the application loading the model.
Affected Products
- stable-diffusion.cpp versions prior to master-584-0a7ae07
- Applications embedding the affected pickle .ckpt parser from src/model.cpp
- Downstream tooling that consumes untrusted .ckpt checkpoints through this library
Discovery Timeline
- 2026-06-16 - CVE-2026-47747 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-47747
Vulnerability Analysis
The vulnerability lives in the pickle deserializer used to load PyTorch legacy .ckpt files. When the parser encounters the BINUNICODE opcode, it reads a 4-byte length prefix that should be treated as an unsigned 32-bit integer. The implementation instead interprets the field using a signed type, allowing values with the high bit set to become large negative numbers.
The parser then forwards this length to memcpy as a size argument. Because memcpy takes a size_t, the negative value is promoted to an extremely large unsigned value, far exceeding the destination buffer. The resulting copy writes attacker-controlled bytes well past the heap allocation, corrupting adjacent chunks and metadata.
Root Cause
The root cause is sign confusion [CWE-122] on the BINUNICODE length field. A signed integer comparison against allocation bounds passes for negative values, and the subsequent unsigned conversion at the memcpy call site bypasses the intended size check. The pickle format itself is also inherently unsafe for untrusted input, which amplifies the impact of any parsing flaw.
Attack Vector
Exploitation requires a victim to load a crafted .ckpt file using an affected build of stable-diffusion.cpp. Attackers distribute malicious checkpoints through model-sharing platforms, repackaged community models, or supply-chain compromise of a legitimate model. User interaction is required, but model loading is a routine workflow in image generation pipelines, so the social engineering bar is low.
// Patch excerpt from src/model.h
// Source: https://github.com/leejet/stable-diffusion.cpp/commit/0a7ae07f948eff4611968a65a22bd7c7031ad74f
bool init_from_gguf_file(const std::string& file_path, const std::string& prefix = "");
bool init_from_safetensors_file(const std::string& file_path, const std::string& prefix = "");
-bool init_from_ckpt_file(const std::string& file_path, const std::string& prefix = "");
+bool init_from_torch_zip_file(const std::string& file_path, const std::string& prefix = "");
+bool init_from_torch_legacy_file(const std::string& file_path, const std::string& prefix = "");
bool init_from_diffusers_file(const std::string& file_path, const std::string& prefix = "");
The patch replaces the monolithic init_from_ckpt_file entry point with split loaders that implement restricted torch legacy checkpoint parsing. See the GitHub Security Advisory GHSA-mghm-5mqc-pwmp and the upstream pull request #1443 for the full change set.
Detection Methods for CVE-2026-47747
Indicators of Compromise
- .ckpt files originating from untrusted sources, mirrors, or model hubs without signature verification
- Crashes or segmentation faults in processes linked against stable-diffusion.cpp during checkpoint loading
- Unexpected child processes or outbound network connections spawned by image generation workloads after a .ckpt load
Detection Strategies
- Inventory binaries and containers embedding stable-diffusion.cpp and confirm the commit hash against master-584-0a7ae07 or later
- Hunt for pickle opcodes such as BINUNICODE in .ckpt files with length prefixes that exceed file size, indicating malformed or hostile payloads
- Correlate process crashes in inference workloads with recent .ckpt downloads or model-store synchronization events
Monitoring Recommendations
- Log file hashes and source URLs for every .ckpt artifact loaded into production inference jobs
- Alert on stable-diffusion.cpp processes that perform execve, shell invocation, or network egress to non-allowlisted destinations
- Monitor model directories for new or modified .ckpt files outside of governed ML pipelines
How to Mitigate CVE-2026-47747
Immediate Actions Required
- Upgrade stable-diffusion.cpp to master-584-0a7ae07 or later across all build and deployment pipelines
- Audit existing .ckpt files in model registries and quarantine any from unverified publishers
- Restrict the user accounts and containers permitted to load .ckpt files to the minimum required privileges
Patch Information
The fix is delivered in commit 0a7ae07f948eff4611968a65a22bd7c7031ad74f via pull request #1443. The change introduces restricted torch legacy checkpoint loading, splitting init_from_ckpt_file into init_from_torch_zip_file and init_from_torch_legacy_file, and corrects the sign handling in the pickle opcode parser.
Workarounds
- Load .ckpt checkpoints only from trusted, signed sources with verified provenance
- Prefer safer formats such as .safetensors and migrate model assets where possible
- Sandbox checkpoint parsing inside a non-privileged process or container with no network access and read-only model storage
# Verify your stable-diffusion.cpp build is patched
cd stable-diffusion.cpp
git fetch --tags
git log --oneline | grep 0a7ae07
# Prefer safetensors over ckpt at runtime
./sd --model /models/weights.safetensors --prompt "..."
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

