You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

CTranslate2 model.bin eager unordered_map::reserve DoS -- reproduction

Sink (source-confirmed at pin 0d8bcd36, model.cc.pin lines 621-622, matching task-cited line numbers exactly):

// Load the variables.
const auto num_variables = consume<uint32_t>(model_file);
model->_variable_index.reserve(num_variables);

_variable_index (model.h.pin:193) is std::unordered_map<std::string, std::shared_ptr<StorageView>>. No cap, no cross-check against remaining file size before the reserve.

Installed wheel: ctranslate2==4.8.1 (pip, matches pinned source behavior -- see results below).

PoC files (15 bytes each)

Layout: u32 binary_version=6 | u16 spec_len=1 | 0x00 (empty spec+NUL) | u32 spec_revision=0 | u32 num_variables

  • model_medium/model.bin: num_variables=0x20000000 (536,870,912) -> ~4.3GB bucket array
  • model_evil/model.bin: num_variables=0xFFFFFFFF (4,294,967,295) -> ~34GB bucket array
  • model_control/model.bin: num_variables=0 (negative control)

Results (WSL2, ~16GB RAM + 4GB swap)

Run num_variables peak VmRSS peak VmHWM wall time outcome
moderate (model_medium) 0x20000000 (~537M) 4.496 GiB 4.496 GiB 4.79s reserve completes (real commit), THEN fails on next field read: RuntimeError: File model.bin is incomplete: failed to read a value of size 2 at position 15
full attack (model_evil), no ulimit 0xFFFFFFFF (~4.29B) 0.234 GiB 0.234 GiB 0.76-0.82s MemoryError: std::bad_alloc -- kernel overcommit heuristic rejects the ~34GB request outright (VM total capacity ~15-16GB RAM + 4GB swap)
full attack (model_evil), ulimit -v 14GB safety cap 0xFFFFFFFF 0.234 GiB 0.234 GiB 0.76s same std::bad_alloc, confirms result is not an artifact of the safety cap
negative control (model_control) 0 0.234 GiB (baseline) 0.234 GiB 0.82s RuntimeError: File model.bin is incomplete: failed to read a value of size 4 at position 15 -- no allocation-related delay/growth at all

Why this proves a REAL commit, not a lazy/demand-paged mapping

The moderate run's peak VmRSS/VmHWM (actual resident pages, sampled live from /proc/<pid>/status while the child ran) climbed to 4.496 GiB -- matching the ~4.3GB predicted from 0x20000000 buckets * 8 bytes/bucket -- and took ~4 seconds of wall time (vs <0.01s for the same-shape but num_variables=0 control). This is libstdc++'s unconditional memset over the newly allocated bucket array inside unordered_map::reserve, executing to completion BEFORE the loader ever reads (and fails on) the next field. 15 bytes of attacker input drove ~4.3 GB of actually-written zero pages: a >300,000,000:1 amplification, and this is nowhere near the ceiling -- num_variables is a fully attacker-controlled uint32_t.

The full-scale payload (num_variables=0xFFFFFFFF, ~34GB request) exceeds this test VM's ~15-16GB RAM + 4GB swap capacity and is rejected immediately by the kernel's memory overcommit heuristic (std::bad_alloc) both with and without an artificial ulimit -v safety net -- confirming the crash is a property of the request size vs. available memory, not a rehearsal artifact. On a target with more RAM (or via swap thrashing / repeated calls), the same 4-byte-controlled value drives a genuine multi-GB-to-tens-of-GB real memory commit / OOM before a single actual model variable is validated.

Reproduction commands (WSL, from /home/wey/fuzz/ct2/poc)

python3 ct2_runner.py ct2_child.py ./model_medium  moderate_4p3GB
python3 ct2_runner.py ct2_child.py ./model_evil    full_attack_34GB
python3 ct2_runner.py ct2_child.py ./model_control negative_control
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