char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

hclgguf-py: validate n_dims and guard against uint64 overflow in reader (#25401)5788b510a

char/aliceai-t5-moe
1.2 KiB37 linesraw
1import struct
2import numpy as np
3import pytest
4
5from gguf.gguf_reader import GGUFReader
6
7
8def _write_gguf(path, n_dims_field, dims):
9    buf = b'GGUF' + struct.pack('<IQQ', 3, 1, 0)  # version 3, 1 tensor, 0 kv
10    name = b'bad_tensor'
11    buf += struct.pack('<Q', len(name)) + name
12    buf += struct.pack('<I', n_dims_field)
13    for d in dims:
14        buf += struct.pack('<Q', d)
15    buf += struct.pack('<I', 0)  # dtype F32
16    buf += struct.pack('<Q', 0)  # tensor offset
17    buf += b'\x00' * 64
18    path.write_bytes(buf)
19
20
21def test_n_dims_upper_bound(tmp_path):
22    # crafted file claims 1_000_000 dims; must be rejected, not read past EOF
23    p = tmp_path / 'evil_ndims.gguf'
24    _write_gguf(p, 1_000_000, [1] * 8)
25    with pytest.raises(ValueError, match='exceeds GGML_MAX_DIMS'):
26        GGUFReader(p)
27
28
29def test_dims_product_no_uint64_wraparound(tmp_path):
30    # dims whose true product overflows uint64; np.prod would wrap to 4 and
31    # silently pass an undersized read. The reader must not accept it.
32    dims = [4194305, 4194305, 211106198978564]
33    assert int(np.prod(np.array(dims, dtype=np.uint64))) == 4  # the wrap bug
34    p = tmp_path / 'evil_overflow.gguf'
35    _write_gguf(p, len(dims), dims)
36    with pytest.raises(ValueError):
37        GGUFReader(p)