|
Download README.md from pragnyanramtha/gguf-python-array-dos-poc: direct link, hf CLI and curl.
- Browser
- Download file 3.43 kB
-
https://huggingface.co/pragnyanramtha/gguf-python-array-dos-poc/resolve/main/README.md
- Command line
-
hf download hf://pragnyanramtha/gguf-python-array-dos-poc/README.md
-
curl -L -o README.md https://huggingface.co/pragnyanramtha/gguf-python-array-dos-poc/resolve/main/README.md
3.43 kB
| # GGUF Python Reader Metadata Array DoS PoC | |
| This repository contains benign GGUF metadata-only files that reproduce resource-exhaustion behavior in the official `gguf` Python package. | |
| ## Summary | |
| `gguf.GGUFReader` parses GGUF array metadata by recursing once per array element and appending one numpy view per element. A small GGUF file with a valid `UINT8` metadata array therefore causes disproportionate CPU and memory use during model metadata loading. A truncated GGUF that declares an extremely large array length also makes the parser keep iterating without advancing because reads past EOF return empty numpy views. | |
| No file here contains executable code, tensor weights, network callbacks, persistence, credential access, or destructive behavior. The marker string is `GGUF_ARRAY_DOS_BENIGN_MARKER`. | |
| ## Tested Versions | |
| - Python 3.13.13 on Windows | |
| - `gguf==0.19.0` | |
| - `numpy==2.4.4` | |
| - llama.cpp source inspected at `78fbbc2c0788efc8857a2c0dc9802ec689fa12c1` | |
| Install command: | |
| ```bash | |
| python -m venv .venv | |
| .venv/Scripts/python -m pip install -r requirements.txt | |
| ``` | |
| On Linux/macOS, use `.venv/bin/python` instead of `.venv/Scripts/python`. | |
| ## Reproduce | |
| Generate fresh artifacts: | |
| ```bash | |
| .venv/Scripts/python make_gguf_array_pocs.py --out artifacts --valid-count 50000 | |
| ``` | |
| Run the trigger with a timeout-isolated child process: | |
| ```bash | |
| .venv/Scripts/python trigger_gguf_array_dos.py artifacts/baseline_small_array.gguf artifacts/valid_uint8_array_50000.gguf artifacts/truncated_huge_uint8_array.gguf --timeout 8 | |
| ``` | |
| Expected result: | |
| - `baseline_small_array.gguf` parses quickly. | |
| - `valid_uint8_array_50000.gguf` is only about 50 KB but creates 50,005 field parts and tens of MB of Python allocations. | |
| - `truncated_huge_uint8_array.gguf` is 140 bytes and times out rather than failing fast. | |
| ## Included Evidence | |
| `array_dos_results_versioned.json`: | |
| - Baseline 141-byte file: `elapsed_sec=0.0009319999990111683`, `tracemalloc_peak_bytes=28813` | |
| - Valid 50,131-byte file: `elapsed_sec=1.5484974999999395`, `tracemalloc_peak_bytes=35335086` | |
| - Truncated 140-byte file: timed out at 8 seconds | |
| `array_dos_results_with_memory.json`: | |
| - Valid 250,131-byte file: `elapsed_sec=12.744927899999311`, `tracemalloc_peak_bytes=176169251` | |
| ## Artifact Hashes | |
| - `artifacts/baseline_small_array.gguf`: `ef66b68d7d9f9690c1c6c27380c5349f435af7ba1d7aebb0dc47cda33f69b12c` | |
| - `artifacts/valid_uint8_array_50000.gguf`: `ead20680b54f62ac1da0cea39fc5f0dc4e0a6ae5e7b0b6b07b22007b7b389e62` | |
| - `artifacts/valid_uint8_array_250000.gguf`: `530cd494fdaf6485f5d29cc90e0bdd54328c7aa41d50dd16cb4c77ec2697e77e` | |
| - `artifacts/truncated_huge_uint8_array.gguf`: `fd98c113e14b2d0212043da98ee1c3cfb369823d99bc41e143fd14bda1390254` | |
| ## Vulnerable Code Path | |
| In `gguf/gguf_reader.py`, `_get_field_parts()` reads `alen` from the file and then loops over every element: | |
| ```python | |
| for idx in range(alen[0]): | |
| curr_size, curr_parts, curr_idxs, curr_types = self._get_field_parts(offs, raw_itype[0]) | |
| aparts += curr_parts | |
| data_idxs += (idx + idxs_offs for idx in curr_idxs) | |
| offs += curr_size | |
| ``` | |
| There is no file-size bound check or bulk scalar-array read. For truncated files, `_get()` returns empty arrays, `curr_size` stays `0`, and the loop continues. | |
| ## Upload Command | |
| If authenticated: | |
| ```bash | |
| huggingface-cli upload YOUR_USERNAME/gguf-python-array-dos-poc C:/Users/Pragnyan/dev/huntr-exp1/ggml/hf_ggml_poc . --repo-type model | |
| ``` | |