Skip to content

Crucible Findings

Vulnerabilities discovered by Crucible's structure-aware fuzzing campaigns across ML model parsers and inference infrastructure. This page lists findings that have been fixed upstream — confirming that the bugs are real, the patches are deployed, and public disclosure is appropriate.

Disclosure policy

Crucible follows a 90-day responsible disclosure timeline. Findings are listed here only after upstream maintainers have merged fixes. For details on the disclosure process, see Responsible Disclosure.

Ecosystem CVEs

For previously-known vulnerabilities across the llama.cpp ecosystem (discovered by other researchers), see Known CVEs.


Summary

Metric Count
Total findings (fixed) 3
Projects with fixes 1
Upstream PRs merged 1

stable-diffusion.cpp

Three vulnerabilities in stable-diffusion.cpp model loading code, all fixed in a single hardening PR by maintainer @wbruna:

Fix: PR #1404 — "chore: harden safetensors and gguf loading code" (merged 2026-04-11, commit 118489e)

ID Bug Class Severity Component Issue CWE
CRUCIBLE-2026-015 Uncaught exception → process crash Medium (5.5) src/model.cpp:318is_safetensors_file() #1395 CWE-248
CRUCIBLE-2026-029 Reachable assertion → process abort Medium (5.5) src/model.cpp:589init_from_safetensors_file() #1396 CWE-617
CRUCIBLE-2026-030 Unbounded allocation → OOM crash High (7.5) src/gguf_reader.hpp:62GGUFReader::read_metadata() #1397 CWE-789

CRUCIBLE-2026-015 — Uncaught JSON Exception in SafeTensors Detection

nlohmann::json::parse() called on untrusted file data without suppressing exceptions. Invalid JSON triggers json::parse_error → uncaught → std::terminate()abort(). The existing header_.is_discarded() guard on the next line is dead code — the exception fires before it can execute.

Fix: Pass false for allow_exceptions parameter so the existing error-handling path works as intended.

CRUCIBLE-2026-029 — GGML_ASSERT Abort on Inconsistent SafeTensors Metadata

GGML_ASSERT(tensor_storage.nbytes() == tensor_data_size) fires when a crafted SafeTensors file has valid JSON header but inconsistent shape/dtype/data_offset metadata. GGML_ASSERT calls ggml_abort() which is not affected by -DNDEBUG, so this crashes all build configurations.

Fix: Replace GGML_ASSERT with an error return that rejects the file gracefully.

CRUCIBLE-2026-030 — Unbounded Memory Allocation in GGUF Reader

std::string key(key_len, '\0') where key_len is a uint64_t read directly from a GGUF file with no bounds checking. Attacker-controlled sizes trigger allocation-size-too-big → std::bad_allocstd::terminate()abort().

Fix: Add bounds check before allocation (1 MiB max key length).


Discovery Method

All findings were discovered using Crucible's libFuzzer harnesses with AddressSanitizer and UndefinedBehaviorSanitizer enabled. The stable-diffusion.cpp findings came from the crucible-libfuzzer-sd-model harness targeting sd_ctx_t model loading.

Crucible's structure-aware mutation engine generates valid-enough model files to pass format detection and reach deep parsing code, while injecting targeted corruptions that trigger edge cases in validation logic.