RustSec logo

HistoryEditJSON (OSV)

RUSTSEC-2026-0217

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

Reported
Issued
Package
tract-nnef (crates.io)
Type
Vulnerability
Categories
Keywords
#parsing #nnef #integer-overflow #out-of-bounds-read
Aliases
References
CVSS Score
6.1 MEDIUM
CVSS Details
Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality Impact
Low
Integrity Impact
None
Availability Impact
High
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H
Patched
  • >=0.21.16, <0.22.0
  • >=0.22.2, <0.23.0
  • >=0.23.1
Affected Functions
Version
tract_nnef::tensors::read_tensor
  • <0.21.16
  • >=0.22.0, <0.22.2
  • >=0.23.0, <0.23.1

Description

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.00.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).

Advisory available under CC0-1.0 license.