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

Check out the documentation for more information.

LLF-002: llamafile ZIP Central Directory Out-of-Bounds Read

Target: Mozilla-Ocho/llamafile File: llamafile/llamafile.c, lines 155-175 (ZIP central directory parsing) Severity: MEDIUM (CWE-125 Out-of-Bounds Read) Reporter: Viridis North LLC | viridisnorthllc@gmail.com

Summary

A crafted .llamafile ZIP container can cause out-of-bounds heap reads during central directory parsing. The EOCD (End of Central Directory) record count field is trusted without validation against the actual central directory size, causing the parsing loop to iterate past valid entries into uninitialized heap memory.

Vulnerable Code

// llamafile.c:155-175
cnt = ZIP_CDIR_RECORDS(eocd);     // from EOCD โ€” UNTRUSTED
cdirsize = ZIP_CDIR_SIZE(eocd);   // from EOCD
cdirdata = malloc(cdirsize);
pread(fd, cdirdata, cdirsize, off);

for (int i = 0; i < cnt; i++) {   // iterates 'cnt' times
    // entry_offset + HDRSIZE check passes for first real entry
    // but after exhausting real entries, reads garbage from heap
    if (ZIP_CFILE_MAGIC(cdirdata + entry_offset) != kZipCfileHdrMagic)
        goto next;  // checks magic โ€” but reads from uninitialized memory first
    // ... memcmp, strndup on potentially OOB data
}

The cnt field from EOCD declares 100 records, but only 1 actual central directory entry exists (56 bytes). After the first valid entry, the loop reads ZIP_CFILE_MAGIC from whatever follows in the malloc'd buffer โ€” uninitialized heap memory.

Attack Vector

User opens a crafted .llamafile file. The ZIP container has a manipulated EOCD record count. During model loading, the central directory parser reads out of bounds, potentially leaking heap contents or crashing.

PoC

llf002_excess_cdir_records.llamafile (142 bytes):

  • Contains 1 valid GGUF model entry in the central directory (56 bytes)
  • EOCD declares cnt=100 records
  • After parsing the 1 real entry, 99 more iterations read from uninitialized heap

Generate PoC (Python)

import struct, zlib
gguf = struct.pack('<II', 0x46554747, 3) + struct.pack('<QQ', 0, 0)
name = b'model.gguf'
# Local file header + Central directory + EOCD with cnt=100
# See full generator in repo

Test

# Build with ASan
make -j$(nproc) CXXFLAGS="-fsanitize=address,undefined -O1 -g" LDFLAGS="-fsanitize=address,undefined"

# Run
ASAN_OPTIONS=detect_leaks=0 ./llamafile --model llf002_excess_cdir_records.llamafile 2>&1
# Expected: heap-buffer-overflow or use-of-uninitialized-value

Impact

  • CWE-125: Out-of-bounds read from heap
  • Heap content disclosure (information leak) or crash (DoS)
  • The uninitialized memory may contain sensitive data from prior allocations

Suggested Fix

Validate cnt against cdirsize before the loop:

if (cnt > cdirsize / kZipCfileHdrMinSize) {
    cnt = cdirsize / kZipCfileHdrMinSize;  // cap to maximum possible entries
}
Downloads last month
10
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support