Skip to content

fix(gguf): reject malformed metadata without panicking - #2

Merged
Vasyl-Trefilov merged 1 commit into
RustingStudio:mainfrom
bettercallcaleb:fix/gguf-malformed-metadata-panics
Nov 4, 2026
Merged

Vasyl-Trefilov merged 1 commit into
RustingStudio:mainfrom
bettercallcaleb:fix/gguf-malformed-metadata-panics

Conversation

@bettercallcaleb

Copy link
Copy Markdown
Contributor

Problem

Opening a malformed GGUF file can panic instead of returning a parsing error. Three independent, very small synthetic files reproduce this on the original main:

Malformed metadata Original behavior
general.alignment = 0 Divide-by-zero panic in div_ceil
Key length u64::MAX Integer overflow in Cur::take
Array element count u64::MAX Vec::with_capacity capacity overflow

Change

  • Use checked offset arithmetic for input reads and alignment, returning descriptive errors.
  • Validate metadata length conversions and reject array counts exceeding remaining bytes.
  • Bound the initial array allocation to avoid trusting file-declared capacities while still supporting larger valid arrays.
  • Add a regression test covering all three failure modes without downloading a model.

Validation

  • Regression test failed against original main with all three panics; passed with this patch.
  • cargo test --test gguf — passed (6 tests).
  • cargo test --lib — passed.
  • cargo test --tests — passed (all integration suites, no model/GPU required for these cases).
  • cargo check — passed.
  • git diff --check — passed.

Tested with Rust 1.98 in an isolated container. Two files changed, one DCO-signed commit, no new dependencies.

This is a local malformed-file robustness fix; no broader security impact is claimed.

Signed-off-by: bettercallcaleb <121191527+bettercallcaleb@users.noreply.github.com>
@Vasyl-Trefilov

Copy link
Copy Markdown
Member

Thanks for contribution!! you are the first ever. I am very happy, thanks again

@Vasyl-Trefilov
Vasyl-Trefilov merged commit 39532ad into RustingStudio:main Nov 4, 2026
Vasyl-Trefilov added a commit that referenced this pull request Nov 4, 2026
Vasyl-Trefilov pushed a commit that referenced this pull request Nov 8, 2026
The analyst and developer hit their per-run step limits during the first
M0-T4 round (analysis and implementation). Raise the budgets to 80 and 160.
Record issue #2 / PR #3 and the in-review status for M0-T4 in the roadmap.
Vasyl-Trefilov pushed a commit that referenced this pull request Nov 8, 2026
* feat(vulkan): account Workgroup shared memory and refuse oversized pipelines

Walk the committed SPIR-V, keep the Workgroup OpVariables and evaluate their
OpTypeArray lengths with the pipeline's specialization map (constants 0..n-1
plus 15 = kv_q8), failing with the opcode on anything unsupported. Vk::new
queries maxComputeSharedMemorySize and logs it on the device line; Vk::pipeline
compares every new pipeline with it and refuses with the kernel, spec, bytes
needed and limit before creating anything (the driver used to accept it and
fault at dispatch, Xid 13 on Volta). STRATA_VK_SMEM_LIMIT overrides the reported
limit so the refusal can be tested without a doctored shader.

* feat(vulkan): preflight the model's pipelines before weights are uploaded

gpu_weight_types derives the weight types a GPU load leaves for the kernels:
upload_type applies Backend::upload's F16 -> F32 and Q4_0/Q5_0 -> Q8_0 rewrites
(experts are copied raw), and the load_part gate (cpu_only, f32_up) is shared
rather than duplicated. Vk::preflight walks the (kernel, spec) pairs each type
reaches, mirroring gemm_raw's COOP split, NT and wpb, and checks them through
the same accounting Vk::pipeline uses: SPIR-V and spec arithmetic only, no
pipeline, model buffer or dispatch. Engine::runner runs it after the backend is
opened and before GpuModel::load_split, so a refusal precedes every weight
upload. The Backend trait gets a no-op default for backends without Workgroup
shared memory.

* feat(cli): add strata check for the Vulkan shared-memory preflight

strata check --model --backend vulkan --device runs the preflight without
loading the model: it lists every checked (kernel, specialization) pair, the
shared-memory limit and the wall-clock cost, and exits non-zero on overflow.
The GPU-free tests assert the measured sizes of the committed SPIR-V
(gemmi_dp: 49152 bytes with Q2_K, 40960 with IQ3_S; the COOP gemmi: 49168) and
the refusal text (kernel, spec, bytes, limit), which Vk::pipeline raises before
it creates anything. The reference-model preflight test skips cleanly without
the model or a Vulkan device.
Vasyl-Trefilov pushed a commit that referenced this pull request Nov 8, 2026
M0-T4 is merged (cf30f29, issue #2 / PR #3): append the V100 window results
(maxComputeSharedMemorySize, checked pairs, forced-overflow refusal, bench
numbers and the no-regression comparison) and mark the task done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants