tensorizer .tensors deserializer β DoS PoC (unbounded allocation + integer overflow)
Proof-of-concept malicious model files for two denial-of-service flaws in the
tensorizer .tensors binary deserializer
(tensorizer==2.12.1, the CoreWeave/vLLM fast model-load format).
Both fire at TensorDeserializer(...) construction (default lazy_load=False), i.e. merely
opening an attacker-supplied .tensors file β no .load() call required.
Affected
- Package:
tensorizer==2.12.1(PyPI latest, 2026-06-20); HEAD652d3c016c84836bba97153e108821c11428ac40. - File:
tensorizer/serialization.py.
Reproduce
python -m venv venv && . venv/bin/activate
pip install tensorizer==2.12.1
# Finding A β unbounded allocation (CWE-789): 73-byte file declares a 256 TiB metadata blob
python -c "import tensorizer; tensorizer.TensorDeserializer('poc_a_meta_281tib.tensors')"
# -> MemoryError at tensorizer/serialization.py:841 (encoded_metadata = reader.read(total_len))
# Finding B β numpy.prod int64 silent overflow (CWE-190): meta-tensor shape wraps the declared size
python -c "import tensorizer; tensorizer.TensorDeserializer('poc_b_neg_assert.tensors')"
# -> AssertionError at tensorizer/serialization.py:3137 (assert is_meta or needed_buffer_size == header.data_length)
# Control β a well-formed file loads cleanly (1 tensor)
python -c "import tensorizer; print(len(list(tensorizer.TensorDeserializer('valid.tensors').keys())), 'tensor')"
Files
| File | Bytes | Trigger |
|---|---|---|
poc_a_meta_281tib.tensors |
73 | Finding A β metadata total_len = 0xFFFFFFFFFFFF (256 TiB) β MemoryError @ serialization.py:841 (main thread, no try). Amplification β 3.86e12Γ. |
poc_a_header_1gib.tensors |
262 KB | Finding A β per-tensor header_len = 1 GiB β bytearray(header_len) allocates 1 GiB with no bound (process RSS 176 β 1200 MiB), proving the missing length check. |
poc_b_neg_assert.tensors |
262 KB | Finding B β v5 long-shape meta-tensor, numpy.prod((2**62, 2)) wraps int64 to -2**63 β AssertionError @ serialization.py:3137. |
valid.tensors |
262 KB | Control β well-formed single-tensor file (loads clean). |
generate_poc_a.py, generate_poc_b.py |
β | Scripts that synthesize the files from a valid baseline. |
Root cause (summary)
- A: file-declared length prefixes (
_MetadataDeserializer.from_iototal_len@:841;_TensorHeaderDeserializer.from_ioheader_len@:646) drive allocations with no upper bound and no check against remaining file size. - B:
TensorEntry.deserialized_length(:231) computesnum_elements = numpy.prod(self.shape)in fixed-width int64, which silently wraps; the wrapped size is summed at:1964and reused as the buffer size, defeating the:3137assert.
Memory-corruption was investigated and refuted β numpy's PyArray_NewFromDescr performs overflow-safe size
arithmetic and a hard buffer-length check, so the impact is process-termination DoS, not OOB read/write.
Proposed fix
- A: bound each file-declared length against the remaining input size (or a configurable cap) before allocating.
- B: compute the element count with arbitrary-precision Python ints (
math.prod) and explicitly overflow-check before allocating.
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support