# 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.