pragnyanramtha commited on
Commit
8921ee7
·
verified ·
1 Parent(s): c6043bd

Expand GGML submission report

Browse files
Files changed (2) hide show
  1. README.md +118 -28
  2. SHA256SUMS.txt +1 -1
README.md CHANGED
@@ -8,43 +8,129 @@ tags:
8
  library_name: other
9
  ---
10
 
11
- # GGML legacy `n_dims` stack out-of-bounds in loaders and quantizers
12
 
13
- This repository contains benign malformed legacy GGML model files that demonstrate model-controlled `n_dims` stack out-of-bounds writes in current GGML legacy loader and quantizer paths.
14
 
15
- ## Submission fields
16
-
17
- - Data format: GGML
18
  - Suggested title: GGML legacy model-controlled `n_dims` stack out-of-bounds in loaders and quantizers
19
  - Severity: High
20
- - Short description: Current GGML legacy loaders and quantizer helpers trust model-controlled `n_dims` and copy dimensions into fixed local arrays. Crafted legacy GGML files trigger ASAN-confirmed stack-buffer-overflow and release-build crashes in GPT-2, GPT-J, SAM, and quantizer paths.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
- ## Summary
23
 
24
- - Affected target verified: ggml `v0.11.1`, commit `a056a26f508b6160438ddd8aabbc859d2a2e7a97`.
25
- - Severity assessment: High, denial of service with native memory corruption. No code execution is claimed.
26
- - Root cause: several legacy parsers read model-controlled `n_dims` and copy dimension entries into fixed local arrays without bounding `n_dims` first.
27
- - Verified outcome: ASAN `stack-buffer-overflow` traces and release-build segmentation faults/aborts.
28
 
29
- ## Included artifacts
30
 
31
- - `artifacts/ggml_gpt2_loader_ndims3.bin`: GPT-2 legacy loader overflow.
32
- - `artifacts/ggml_gptj_loader_ndims64.bin`: GPT-J legacy loader overflow.
33
- - `artifacts/ggml_sam_loader_ndims64.bin`: SAM legacy loader overflow.
34
- - `artifacts/ggml_gpt2_quant_ndims1024.bin`: GPT-2 quantizer common loader overflow.
35
- - `artifacts/ggml_gptj_quant_ndims1024.bin`: GPT-J quantizer common loader overflow.
36
- - `logs/*.txt`: ASAN traces from the vulnerable binaries.
37
- - `modelscan/*`: scanner output captured during verification.
38
- - `scripts/*`: local generators used to create the PoC files.
39
 
40
- ## Verified crash sites
41
 
42
- - GPT-2 loader: `examples/gpt-2/main-backend.cpp`, local `ne[2]`.
43
- - GPT-J loader: `examples/gpt-j/main.cpp`, local `ne[2]`.
44
- - SAM loader: `examples/sam/sam.cpp`, local `ne[4]`.
45
- - Quantizers: `examples/common-ggml.cpp`, local `ne[4]`.
46
 
47
- ## SHA256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  ```text
50
  62892adf21342a70b3c6dee5adfa224a435f747a5e6eb7c84e5064f576e99b0c artifacts/ggml_gpt2_loader_ndims3.bin
@@ -54,6 +140,10 @@ d9a5880f374d68f1c618945e301997b454317e203d23ca35b3d7c11bd69b8ddb artifacts/ggml
54
  002f3224ac62b36bc9b60da7fa1e5a4ac24f1587552846c10bec8cf3dbf7e928 artifacts/ggml_gptj_quant_ndims1024.bin
55
  ```
56
 
57
- ## Safety note
 
 
 
 
58
 
59
- These are intentionally malformed model files for security reproduction. Do not load them in production processes.
 
8
  library_name: other
9
  ---
10
 
11
+ # GGML legacy model-controlled `n_dims` stack out-of-bounds in loaders and quantizers
12
 
13
+ ## Submission
14
 
15
+ - Data format: GGML legacy model files
 
 
16
  - Suggested title: GGML legacy model-controlled `n_dims` stack out-of-bounds in loaders and quantizers
17
  - Severity: High
18
+ - Impact: native memory corruption and reliable denial of service when a victim loads or quantizes a malicious GGML model file
19
+ - Affected target verified: ggml `v0.11.1`, commit `a056a26f508b6160438ddd8aabbc859d2a2e7a97`
20
+ - Not claimed: arbitrary code execution
21
+
22
+ ## Executive summary
23
+
24
+ Several GGML legacy model readers trust the model-controlled `n_dims` field before copying tensor dimensions into fixed-size stack arrays. A malicious GGML artifact can set `n_dims` larger than the destination array and cause an out-of-bounds stack write during normal model loading or quantization.
25
+
26
+ This repository includes five minimal malformed GGML files that hit independent loader/tool paths:
27
+
28
+ - GPT-2 loader, fixed local `ne[2]`
29
+ - GPT-J loader, fixed local `ne[2]`
30
+ - SAM loader, fixed local `ne[4]`
31
+ - GPT-2 quantizer helper, fixed local `ne[4]`
32
+ - GPT-J quantizer helper, fixed local `ne[4]`
33
 
34
+ The issue is artifact-carried: the only attacker-controlled input is the GGML model file passed to the normal loader/quantizer command. ASAN reports stack-buffer-overflow, and release builds crash/abort.
35
 
36
+ ## Why this is security-relevant
 
 
 
37
 
38
+ GGML artifacts are commonly exchanged as model files and are loaded by native C/C++ tools. The parser reaches the vulnerable path before model execution and before meaningful model validation. A service that accepts, previews, converts, or quantizes untrusted GGML models can be crashed by a tiny file. The ASAN traces show a write beyond a stack buffer, which is stronger than a clean parser error or expected unsupported-format rejection.
39
 
40
+ ## Root cause
 
 
 
 
 
 
 
41
 
42
+ The vulnerable code pattern is:
43
 
44
+ 1. Read `n_dims` from the file.
45
+ 2. Allocate a fixed local dimension array such as `int32_t ne[2]` or `int32_t ne[4]`.
46
+ 3. Read `n_dims` dimension entries from the file directly into that fixed array.
47
+ 4. Validate/use tensor metadata after the out-of-bounds write has already happened.
48
 
49
+ Verified crash locations:
50
+
51
+ - `examples/gpt-2/main-backend.cpp`, local `ne[2]`
52
+ - `examples/gpt-j/main.cpp`, local `ne[2]`
53
+ - `examples/sam/sam.cpp`, local `ne[4]`
54
+ - `examples/common-ggml.cpp`, local `ne[4]`, reached by GPT-2 and GPT-J quantizers
55
+
56
+ ## Repository contents
57
+
58
+ ```text
59
+ artifacts/ggml_gpt2_loader_ndims3.bin GPT-2 loader PoC
60
+ artifacts/ggml_gptj_loader_ndims64.bin GPT-J loader PoC
61
+ artifacts/ggml_sam_loader_ndims64.bin SAM loader PoC
62
+ artifacts/ggml_gpt2_quant_ndims1024.bin GPT-2 quantizer PoC
63
+ artifacts/ggml_gptj_quant_ndims1024.bin GPT-J quantizer PoC
64
+ logs/*.txt ASAN traces
65
+ modelscan/* ModelScan outputs from verification
66
+ scripts/* PoC generation scripts
67
+ SHA256SUMS.txt hash manifest
68
+ ```
69
+
70
+ ## Reproduction
71
+
72
+ Build the affected targets with AddressSanitizer:
73
+
74
+ ```bash
75
+ git clone https://github.com/ggml-org/ggml.git
76
+ cd ggml
77
+ git checkout a056a26f508b6160438ddd8aabbc859d2a2e7a97
78
+ cmake -S . -B build-asan -DCMAKE_BUILD_TYPE=Debug \
79
+ -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
80
+ -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
81
+ -DGGML_NATIVE=OFF
82
+ cmake --build build-asan --target gpt-2-backend gpt-j sam gpt-2-quantize gpt-j-quantize -j
83
+ ```
84
+
85
+ Download this repository and run the loader cases:
86
+
87
+ ```bash
88
+ hf download pragnyanramtha/ggml-legacy-ndims-oob-suite --local-dir ggml-ndims-poc
89
+
90
+ ./build-asan/bin/gpt-2-backend -m ggml-ndims-poc/artifacts/ggml_gpt2_loader_ndims3.bin -p test -n 1
91
+ ./build-asan/bin/gpt-j -m ggml-ndims-poc/artifacts/ggml_gptj_loader_ndims64.bin -p test -n 1
92
+ ./build-asan/bin/sam -m ggml-ndims-poc/artifacts/ggml_sam_loader_ndims64.bin -i /tmp/nonexistent.jpg
93
+ ```
94
+
95
+ Run the quantizer cases:
96
+
97
+ ```bash
98
+ ./build-asan/bin/gpt-2-quantize ggml-ndims-poc/artifacts/ggml_gpt2_quant_ndims1024.bin /tmp/gpt2-out.bin q4_0
99
+ ./build-asan/bin/gpt-j-quantize ggml-ndims-poc/artifacts/ggml_gptj_quant_ndims1024.bin /tmp/gptj-out.bin q4_0
100
+ ```
101
+
102
+ Expected ASAN result for the quantizer path:
103
+
104
+ ```text
105
+ ERROR: AddressSanitizer: stack-buffer-overflow
106
+ WRITE of size 4
107
+ ggml_common_quantize_0(...) examples/common-ggml.cpp:114
108
+ This frame has ... 'ne' (line 112) <== Memory access ... overflows this variable
109
+ ```
110
+
111
+ Expected ASAN result for the SAM loader path:
112
+
113
+ ```text
114
+ ERROR: AddressSanitizer: stack-buffer-overflow
115
+ sam_model_load(...) examples/sam/sam.cpp:1058
116
+ 'ne' (line 1054) <== Memory access ... overflows this variable
117
+ ```
118
+
119
+ Expected ASAN result for the GPT loader paths:
120
+
121
+ ```text
122
+ ERROR: AddressSanitizer: stack-buffer-overflow
123
+ SUMMARY: AddressSanitizer: stack-buffer-overflow ... in memcpy
124
+ 'ne' (...) <== Memory access ... overflows this variable
125
+ ```
126
+
127
+ The captured traces are included in `logs/`.
128
+
129
+ ## Scanner behavior
130
+
131
+ The artifacts were also scanned with ModelScan during local verification. They are malformed GGML parser tests, not executable payloads, and the scanner did not identify the native parser memory corruption. The scanner logs are included under `modelscan/`.
132
+
133
+ ## Hashes
134
 
135
  ```text
136
  62892adf21342a70b3c6dee5adfa224a435f747a5e6eb7c84e5064f576e99b0c artifacts/ggml_gpt2_loader_ndims3.bin
 
140
  002f3224ac62b36bc9b60da7fa1e5a4ac24f1587552846c10bec8cf3dbf7e928 artifacts/ggml_gptj_quant_ndims1024.bin
141
  ```
142
 
143
+ ## Suggested fix
144
+
145
+ Reject tensors where `n_dims` exceeds the destination capacity before reading dimension entries. Prefer reading into a dynamically sized container only after bounding `n_dims` to a format-level maximum. Add regression tests for oversized `n_dims` in each legacy loader and shared quantizer helper.
146
+
147
+ ## Limitations
148
 
149
+ This is a denial-of-service/native-memory-corruption report. I am not claiming arbitrary code execution. The PoCs are intentionally tiny malformed model files and should only be loaded in a throwaway test environment.
SHA256SUMS.txt CHANGED
@@ -1,4 +1,4 @@
1
- 22875f664cdc9c2880902e8c7c2d318a051cdc2bf98c2b86543a53a26612ff76 ./README.md
2
  62892adf21342a70b3c6dee5adfa224a435f747a5e6eb7c84e5064f576e99b0c ./artifacts/ggml_gpt2_loader_ndims3.bin
3
  d9a5880f374d68f1c618945e301997b454317e203d23ca35b3d7c11bd69b8ddb ./artifacts/ggml_gpt2_quant_ndims1024.bin
4
  a0f8d2a774f739c6580e51348aa30f455de29c7a774b1f25c3ca27a593fae224 ./artifacts/ggml_gptj_loader_ndims64.bin
 
1
+ a37d87c867aad3ddb9da6a051d7235707cf96fe32a747686b1341a7cc01cfd62 ./README.md
2
  62892adf21342a70b3c6dee5adfa224a435f747a5e6eb7c84e5064f576e99b0c ./artifacts/ggml_gpt2_loader_ndims3.bin
3
  d9a5880f374d68f1c618945e301997b454317e203d23ca35b3d7c11bd69b8ddb ./artifacts/ggml_gpt2_quant_ndims1024.bin
4
  a0f8d2a774f739c6580e51348aa30f455de29c7a774b1f25c3ca27a593fae224 ./artifacts/ggml_gptj_loader_ndims64.bin