ollama qwen3next converter unbounded allocation PoC (source-verified)

Proof-of-concept material for a huntr Model Format Vulnerability report against ollama/ollama, convert/convert_qwen3next.go:226-233 (qwen3NextInferNextNPredictLayers).

The bug, verified against the live source fetched directly today

var n int64
if err := binary.Read(f, binary.LittleEndian, &n); err != nil {
    f.Close()
    return 0, err
}
b := bytes.NewBuffer(make([]byte, 0, n))
if _, err = io.CopyN(b, f, n); err != nil {
    f.Close()
    return 0, err
}

An 8-byte little-endian int64 length is read directly from an untrusted model file and used, with no upper-bound check, to pre-allocate a buffer via make([]byte, 0, n). Three sibling functions in the SAME repository that read the same kind of field (headerSize) have a working guard (x/mlxrunner/model/root.go:144, x/imagegen/manifest/manifest.go:295, x/server/show.go:383 - all three do if headerSize > N*1024*1024 { return err } before make()) - the fix pattern is already known and used elsewhere in this codebase, just not applied here.

evil_qwen3next_header.bin is the 8-byte little-endian int64 header this function reads first: value 2^48 (281,474,976,710,656) - large enough to be a real denial-of-service pressure on heap-arena metadata (positive, so it avoids the separate int64 sign caveat noted below), while still small enough to encode in 8 bytes.

Reachability: server/create.go:571 -> convert/convert.go:407 (ConvertModel) -> convert/convert.go:414 (parseTensors) is the sole call chain into model conversion, triggered by the public HTTP route POST /api/create (server/routes.go:1891) - reachable without authentication on unprotected local/private deployments.

Honest limits (not swept under the rug)

  • No Go toolchain was available on this host to build ollama and run this live - confidence rests on direct reading of the current source (this function, the three sibling functions with a working guard, and the call chain), not a live crash.
  • n is int64, not uint64 - if the file's 8th byte has the top bit set, n is negative, which causes a recoverable panic (makeslice: cap out of range), not a large allocation. Real DoS requires n in the positive range shown above, not merely "attacker sets all bits".
  • Duplicate note: the sibling instance of this exact pattern in convert/reader_safetensors.go:41-48 (parseSafetensors, the safetensors format's own entry point) is ALREADY publicly reported - ollama/ollama issue #17148 and PR #17149 (opened 2026-07-12 by a third party, still open/unmerged as of today) describe exactly that file/function. This report deliberately covers ONLY the separate convert_qwen3next.go instance, which is NOT touched by PR #17149's diff and remains unreported.

Impact: Denial of Service - a small (a few bytes) crafted model file with a qwen3next architecture, imported via the public /api/create endpoint, can force a large buffer pre-allocation before any content validation.

Suggested fix: Apply the same headerSize > N*1024*1024-style guard already used in x/mlxrunner/model/root.go, x/imagegen/manifest/manifest.go, and x/server/show.go to convert_qwen3next.go:226-233 as well.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support