You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

Proof of Concept: Embedded-NUL Metadata Key Canonicalization Mismatch in GGUF Reserved-Key Lookup

This repository contains a deterministic PoC for a GGUF parsing issue in llama.cpp.

The issue is simple: GGUF metadata keys are parsed as length-prefixed strings, but some reserved-key lookups in llama.cpp later use C-string comparison. That creates a mismatch for keys containing an embedded NUL byte. During duplicate validation, keys such as general.alignment and general.alignment\0evil are treated as different. During reserved-key lookup, they collapse to the same logical key.

The result is order-dependent metadata resolution inside llama.cpp. The same GGUF file is also interpreted differently by gguf-py, which keeps exact string semantics throughout.

What This PoC Shows

There are two main cases in generated/.

1. Alignment aliasing

alias_first.gguf contains:

  • general.alignment\0evil = 32
  • general.alignment = 4096

Observed behavior:

  • gguf-py resolves alignment to 4096
  • llama.cpp resolves alignment to 32

Because alignment controls the start of the tensor data section, the two implementations end up reading different payload bytes from the same file.

plain_first.gguf swaps only the metadata order. In that case, both implementations resolve 4096. That shows the llama.cpp result is order-dependent.

2. Another reserved key

architecture_alias_first.gguf contains:

  • general.architecture\0evil = "AAA"
  • general.architecture = "llama"

Observed behavior:

  • gguf-py resolves general.architecture to llama
  • llama.cpp resolves general.architecture to AAA

This demonstrates that the issue is not limited to general.alignment.

Why It Happens

At a high level, the bug is:

  • parse keys as full strings
  • validate duplicates using full-string equality
  • later resolve reserved keys using strcmp()

That last step introduces truncation at the first embedded NUL byte.

Repository Layout

  • create_poc.py Builds the GGUF files from scratch. No external model files are needed.
  • verify_python.py Verifies behavior with gguf-py.
  • verify_llamacpp.sh Builds a small gguf_init_from_file() harness and verifies behavior with llama.cpp.
  • verify_payloads.py Confirms the tensor payload differential.
  • run_all.sh Runs the full flow and compares the result with expected_output.txt.
  • generated/ Contains the deterministic GGUF samples.

Reproduction

Prerequisites:

  • Python 3
  • a local llama.cpp checkout at ../llama.cpp, or LLAMA_CPP_DIR=/path/to/llama.cpp
  • CMake and a working C++ compiler

Run:

./run_all.sh

That command regenerates the GGUF files, runs the Python-side verification, builds and runs the llama.cpp harness, checks the payload differential, and diffs the combined output against expected_output.txt.

Expected Results

For alias_first.gguf:

  • gguf-py reports alignment = 4096
  • llama.cpp reports alignment = 32
  • gguf-py reads PYTHON____PAYLD!
  • llama.cpp reads CPLUSPLUS_PAYLD!

For plain_first.gguf:

  • both implementations resolve alignment = 4096
  • both read the same payload

For architecture_alias_first.gguf:

  • gguf-py resolves general.architecture to llama
  • llama.cpp resolves general.architecture to AAA

Notes

This PoC is focused on the parser differential itself. It does not rely on prompt behavior, tokenizer semantics, or model policy. The generated files are intentionally small and only exercise the metadata and tensor-layout paths needed to show the inconsistency.

Downloads last month
11
GGUF
Model size
32 params
Architecture
llama
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