VDB
Sign up
MEDIUM6.1

RUSTSEC-2026-0217

Integer overflow in tract-nnef NNEF tensor parser leads to out-of-bounds read on model load

Details

`tract_nnef::tensors::read_tensor` builds a tensor shape from attacker-controlled 32-bit dimensions and computes both the element count `product(shape)` and the byte allocation `product(shape) * size_of(dt)` with **unchecked `usize` arithmetic**. In release builds (no `overflow-checks`) both products wrap modulo 2^64.

A crafted NNEF `.dat` tensor can choose dimensions whose wrapped products collapse to a small value that satisfies the header size-consistency check, while the true element count stays astronomically large. `read_tensor` then returns a `Tensor` whose reported `len` (e.g. `2^61 + 7`) far exceeds its backing heap allocation (e.g. 56 bytes). The unchecked accessor `as_slice_unchecked` (`slice::from_raw_parts(ptr, self.len())`) subsequently yields a slice spanning ~18 EiB over the small buffer.

The out-of-bounds read fires automatically during model build (no inference required), reachable through the default `DatLoader` resource loader via the public `tract_nnef::nnef().model_for_path` / `model_for_read` API when the const-folding `as_uniform` fast-path materializes the over-long constant. The always-on primitive is a bounded adjacent-heap over-read (information disclosure); access further past the mapped region SIGSEGVs (denial of service). No out-of-bounds write or code execution was demonstrated.

Affected: every release line prior to the backported fixes — `< 0.21.16`, `0.22.0`–`0.22.1`, and `0.23.0`. The block-quant path had already received an analogous blob-size guard; the dense `DatLoader` path was missed.

## Mitigation

Upgrade to `0.21.16`, `0.22.2`, or `0.23.1`. The fix computes the shape product and byte size with `checked_mul` and rejects the tensor on overflow (commit [`34c7df2`](https://github.com/sonos/tract/commit/34c7df2c9bd2a36583e09b52f3e6319bf23102e8)).

Are you affected?

Enter the version of the package you're using.

Affected packages

crates.io/tract-nnef
Introduced in: 0.0.0-0Fixed in: 0.21.16

Upgrade tract-nnef to 0.21.16 or newer (ecosystem crates.io).

References