CWE-125
AllowedOut-of-bounds Read
Abstraction: Base · Status: Draft
The product reads data past the end, or before the beginning, of the intended buffer.
12317 vulnerabilities reference this CWE, most recent first.
GHSA-X55X-FV3C-R279
Vulnerability from github – Published: 2022-05-14 01:52 – Updated: 2022-05-14 01:52There exists a heap-based buffer over-read in ff_vc1_pred_dc in vc1_block.c in Libav 12.3, which allows attackers to cause a denial-of-service via a crafted aac file.
{
"affected": [],
"aliases": [
"CVE-2018-18827"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2018-10-30T06:29:00Z",
"severity": "MODERATE"
},
"details": "There exists a heap-based buffer over-read in ff_vc1_pred_dc in vc1_block.c in Libav 12.3, which allows attackers to cause a denial-of-service via a crafted aac file.",
"id": "GHSA-x55x-fv3c-r279",
"modified": "2022-05-14T01:52:47Z",
"published": "2022-05-14T01:52:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-18827"
},
{
"type": "WEB",
"url": "https://bugzilla.libav.org/show_bug.cgi?id=1135"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X577-J4FF-CQXW
Vulnerability from github – Published: 2022-10-14 19:00 – Updated: 2022-10-18 19:00The HwAirlink module has an out-of-bounds read vulnerability.Successful exploitation of this vulnerability may cause information leakage.
{
"affected": [],
"aliases": [
"CVE-2022-38981"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-10-14T16:15:00Z",
"severity": "HIGH"
},
"details": "The HwAirlink module has an out-of-bounds read vulnerability.Successful exploitation of this vulnerability may cause information leakage.",
"id": "GHSA-x577-j4ff-cqxw",
"modified": "2022-10-18T19:00:35Z",
"published": "2022-10-14T19:00:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-38981"
},
{
"type": "WEB",
"url": "https://device.harmonyos.com/en/docs/security/update/security-bulletins-phones-202210-0000001416095697"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-X57R-5929-78VM
Vulnerability from github – Published: 2022-09-14 00:00 – Updated: 2022-09-14 00:00Windows Remote Access Connection Manager Information Disclosure Vulnerability.
{
"affected": [],
"aliases": [
"CVE-2022-35831"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-09-13T19:15:00Z",
"severity": "MODERATE"
},
"details": "Windows Remote Access Connection Manager Information Disclosure Vulnerability.",
"id": "GHSA-x57r-5929-78vm",
"modified": "2022-09-14T00:00:44Z",
"published": "2022-09-14T00:00:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-35831"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-35831"
},
{
"type": "WEB",
"url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2022-35831"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-X5CX-QFRC-RW4R
Vulnerability from github – Published: 2024-01-09 18:30 – Updated: 2024-01-09 18:30Microsoft Virtual Hard Disk Elevation of Privilege Vulnerability
{
"affected": [],
"aliases": [
"CVE-2024-20658"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-01-09T18:15:48Z",
"severity": "HIGH"
},
"details": "Microsoft Virtual Hard Disk Elevation of Privilege Vulnerability",
"id": "GHSA-x5cx-qfrc-rw4r",
"modified": "2024-01-09T18:30:28Z",
"published": "2024-01-09T18:30:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-20658"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-20658"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X5G9-XHF2-HRJ6
Vulnerability from github – Published: 2026-03-17 21:31 – Updated: 2026-03-17 21:31An out-of-bounds read vulnerability exists in the EMF functionality of Canva Affinity. By using a specially crafted EMF file, an attacker could exploit this vulnerability to perform an out-of-bounds read, potentially leading to the disclosure of sensitive information.
{
"affected": [],
"aliases": [
"CVE-2025-62500"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-17T19:15:58Z",
"severity": "MODERATE"
},
"details": "An out-of-bounds read vulnerability exists in the EMF functionality of Canva Affinity. By using a specially crafted EMF file, an attacker could exploit this vulnerability to perform an out-of-bounds read, potentially leading to the disclosure of sensitive information.",
"id": "GHSA-x5g9-xhf2-hrj6",
"modified": "2026-03-17T21:31:45Z",
"published": "2026-03-17T21:31:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62500"
},
{
"type": "WEB",
"url": "https://talosintelligence.com/vulnerability_reports/TALOS-2025-2298"
},
{
"type": "WEB",
"url": "https://trust.canva.com/?tcuUid=1f728b0d-17f3-4c9c-97e9-6662b769eb62"
},
{
"type": "WEB",
"url": "https://www.talosintelligence.com/vulnerability_reports/TALOS-2025-2298"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-X5H6-WMMC-R9X2
Vulnerability from github – Published: 2022-05-24 19:06 – Updated: 2022-05-24 19:06The vgacon subsystem in the Linux kernel before 5.8.10 mishandles software scrollback. There is a vgacon_scrolldelta out-of-bounds read, aka CID-973c096f6a85.
{
"affected": [],
"aliases": [
"CVE-2020-28097"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-06-24T12:15:00Z",
"severity": "HIGH"
},
"details": "The vgacon subsystem in the Linux kernel before 5.8.10 mishandles software scrollback. There is a vgacon_scrolldelta out-of-bounds read, aka CID-973c096f6a85.",
"id": "GHSA-x5h6-wmmc-r9x2",
"modified": "2022-05-24T19:06:12Z",
"published": "2022-05-24T19:06:12Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-28097"
},
{
"type": "WEB",
"url": "https://github.com/torvalds/linux/commit/973c096f6a85e5b5f2a295126ba6928d9a6afd45"
},
{
"type": "WEB",
"url": "https://cdn.kernel.org/pub/linux/kernel/v5.x/ChangeLog-5.8.10"
},
{
"type": "WEB",
"url": "https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=973c096f6a85e5b5f2a295126ba6928d9a6afd45"
},
{
"type": "WEB",
"url": "https://seclists.org/oss-sec/2020/q3/176"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20210805-0001"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:P/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X5MR-F43M-7R93
Vulnerability from github – Published: 2025-09-17 09:30 – Updated: 2025-09-17 09:30An Out-Of-Bounds Read vulnerability affecting the PAR file reading procedure in SOLIDWORKS eDrawings on Release SOLIDWORKS Desktop 2025 could allow an attacker to execute arbitrary code while opening a specially crafted PAR file.
{
"affected": [],
"aliases": [
"CVE-2025-9447"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-17T07:15:42Z",
"severity": "HIGH"
},
"details": "An Out-Of-Bounds Read vulnerability affecting the PAR file reading procedure in SOLIDWORKS eDrawings on Release SOLIDWORKS Desktop 2025 could allow an attacker to execute arbitrary code while opening a specially crafted PAR file.",
"id": "GHSA-x5mr-f43m-7r93",
"modified": "2025-09-17T09:30:44Z",
"published": "2025-09-17T09:30:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-9447"
},
{
"type": "WEB",
"url": "https://www.3ds.com/trust-center/security/security-advisories/cve-2025-9447"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X5MV-8WGW-29HG
Vulnerability from github – Published: 2026-06-18 15:05 – Updated: 2026-06-18 15:05- Component:
tract-nnef(nnef/src/tensors.rs::read_tensor) +tract-data(data/src/tensor.rs) - Affected versions:
< 0.21.16,0.22.0–0.22.2,0.23.0–0.23.1— the denseDatLoaderpath was unguarded across all three release lines; patched in 0.21.16 / 0.22.2 / 0.23.1 - Class: CWE-190 (integer overflow) → CWE-125 (out-of-bounds read)
- Trigger: loading a crafted NNEF model archive (
*.nnef.tgz/*.nnef.tar/ dir) via the publictract_nnef::nnef().model_for_path/model_for_read - Impact:
read_tensorreturns a memory-unsafe tensor (reportedlen2^61 over a 56-byte heap allocation). Always-on primitive: a bounded heap out-of-bounds read during model build (as_uniform), an adjacent-heap information-disclosure reachable via the public load API. The resulting slice is an unsoundfrom_raw_parts(ptr, 2^61)that SIGSEGVs (DoS) on any access past the mapped region (demonstrated by direct access). No out-of-bounds write and no RCE were achieved — tract's const-folding/as_uniformfast-paths fold simple consuming graphs without the full read. - Severity: Medium
Summary
read_tensor builds a tensor shape from attacker-controlled 32-bit dimensions and computes the element count len = product(shape) and the byte allocation product(shape) * size_of(dt) with unchecked usize arithmetic. In --release (no overflow-checks), both products wrap modulo 2^64. An attacker chooses dimensions so that the wrapped products collapse to a small value that satisfies the header consistency check, while the true element count remains astronomically large. read_tensor returns Ok with a Tensor whose reported len (e.g. 2^61+7) is far larger than its backing heap allocation (e.g. 56 bytes). The unchecked slice accessor as_slice_unchecked (from_raw_parts(ptr, self.len)) then produces a slice spanning ~18 exabytes over a 56-byte buffer. The out-of-bounds read fires automatically during model build (no inference required), reachable through the default DatLoader resource loader.
Root cause
nnef/src/tensors.rs, read_tensor:
let shape: TVec<usize> = header.dims[0..header.rank as usize].iter().map(|d| *d as _).collect();
let len = shape.iter().product::<usize>(); // (1) unchecked, wraps
...
} else if header.bits_per_item != u32::MAX
&& len * (header.bits_per_item as usize / 8) != header.data_size_bytes as usize // (2) wrapped == u32
{
bail!(...);
}
...
let mut tensor = unsafe { Tensor::uninitialized_dt(dt, &shape)? }; // (3) alloc off the same wrapped product
...
reader.read_exact(plain.as_bytes_mut())?; // storage-bounded read, no overflow here
Ok(tensor)
data/src/tensor.rs, uninitialized_aligned_dt:
let bytes = shape.iter().cloned().product::<usize>() * dt.size_of(); // (3) wraps to the same small value
let storage = ... Blob::new_for_size_and_align(bytes, alignment) ...;
...
tensor.update_strides_and_len(); // len = product(shape), wraps, no clamp
The three quantities — the consistency-check LHS (2), the allocation (3), and the reported len — are all the same wrapped product(shape)*size_of, so they stay mutually consistent and the consistency check at (2) cannot catch the overflow. data_size_bytes is a u32, so the attacker simply sets it to the wrapped value.
Corruption sink — data/src/tensor.rs::as_slice_unchecked (and data/src/tensor/plain_view.rs::as_slice_unchecked):
if self.storage.byte_len() == 0 { &[] }
else { std::slice::from_raw_parts(self.as_ptr_unchecked(), self.len()) } // len = 2^61 over a 56-byte alloc
The only guard is byte_len() == 0. A small non-zero allocation defeats it and yields an unsound oversized slice.
Witness (F64)
dims = [33955849, 7005787, 359, 3, 3, 3] (rank 6, each <= u32::MAX)
product(shape)= 2_305_843_009_213_693_959 = 2^61 + 7
bits_per_item = 64 (F64), item_type = 0, item_type_vendor = 0
data_size_bytes = 56 # == (2^61+7)*8 mod 2^64
len * (bits/8) mod 2^64 = (2^61+7)*8 mod 2^64 = 56 == data_size_bytes→ consistency check passes.- allocation =
(2^61+7)*8 mod 2^64 = 56bytes (7 × F64). - reported
len=2^61+7elements.
Only the is_copy() numeric arms (F16/F32/F64/int, and likely the complex arms) are exploitable. F64 is the cleanest (bits/8 divides evenly). The bool, String, and block-quant paths are each guarded by an independent mechanism (size_of==1 prevents byte/element divergence; String bails on a missing num_traits::Zero impl; block-quant has its own ensure!(expected_len == data_size_bytes) and uses non-plain Exotic storage).
Reachability (load-time, public API)
nnef().model_for_read(tar)
-> proto_model_for_read nnef/src/framework.rs:303
-> DatLoader.try_load (any *.dat) nnef/src/resource.rs:97 (default loader, framework.rs:33)
-> read_tensor -> Ok(Tensor{len=2^61+7, storage=56B}) nnef/src/tensors.rs:61
-> into_typed_model -> variable() fragment nnef/src/ops/nnef/deser.rs:74
ensure!(tensor.shape() == &*shape) deser.rs:122 (attacker matches shape in graph.nnef -> passes)
-> Const::new -> wire_node core/src/model/typed.rs:67
-> Const::output_facts core/src/ops/konst.rs:54
-> TypedFact::try_from core/src/model/fact.rs:459
-> Tensor::as_uniform -> is_uniform_t::<f64> data/src/tensor.rs:1099
-> as_slice_unchecked::<f64> data/src/tensor.rs:1044
-> from_raw_parts(ptr, 2^61+7) over 56-byte buffer -> OOB READ
No shape-vs-storage re-validation exists anywhere on this path (proto.validate() checks only the AST; Const::new checks only is_plain; check_for_access checks only the datum type; even the safe PlainView::as_slice does from_raw_parts(ptr, self.len) with no length guard).
Execution (proof of concept)
Reproduced against the crate at the affected revision, --release, x86_64-linux. Three scenarios:
- Direct
read_tensor— feed the crafted 128-byte header + 56-byte payload: read_tensor -> Ok,shape=[33955849,7005787,359,3,3,3],len()=2305843009213693959,as_bytes().len()=56,as_slice::<f64>().len()=2305843009213693959.s[7](first element past the 56-byte allocation) returns0x0000000000000041→ heap OOB read (adjacent-heap disclosure).s[1<<40]→ SIGSEGV (signal 11).- Public load API — build a malicious
.nnef.tar(graph.nnefwithvariable(label='weights', shape=[...])+weights.dat) and callnnef().model_for_read(): - returns
Okwith oneConstnode,out[0].fact.uniform=Some(...),len()=2305843009213693959over a 56-byte buffer → confirmsas_uniform/is_uniform_t/as_slice_uncheckedperformed an OOB read on load (bounded over-read here becauseis_uniform's.all()short-circuits on the uniform0x41payload). - Optimized graph — same archive but the const is consumed (
output = mul(weights, weights)), theninto_optimized/run: - Does not crash. With both a uniform (
0x41×56) and a non-uniform (0..56) payload,into_optimizedconst-foldsmul(const, const)to a single node without a full-length materialization of the oversized const, andruncompletes. A reliable arbitrary-length crash through a normal optimized graph was therefore NOT demonstrated; the always-on primitive is the bounded load-time over-read (scenario 2), and the wild-slice SIGSEGV is shown via direct access (scenario 1).
Runnable PoC sources are available to the maintainers on request.
Detection
- Static: flag
*.iter().product::<usize>()over externally-controlled dimensions withoutchecked_*/try_into, especially when the result feeds an allocation and a separately-trackedlen. - Runtime / fleet: crash telemetry showing SIGSEGV inside
is_uniform_t/from_raw_partsduring NNEF model load; an ASAN build flagsheap-buffer-overflow READinread_tensor→as_uniform. - Input filter (compensating): reject NNEF
.dattensors whereproduct(dims)overflowsu64, or whereproduct(dims) * size_of(dt) != data_size_bytescomputed in checked arithmetic, before constructing the tensor. - YARA-ish heuristic for
.datblobs: NNEF magic4E EF 01 00,rank<=8, and anydim >= 0x10000whose checked product with the others overflows.
Mitigation (suggested fix)
In read_tensor, compute the element count and byte size with checked arithmetic and reject on overflow, mirroring the guard already present on the block-quant path (ensure!(expected_len == data_size_bytes) added in eacd13ccb):
let len = shape.iter().try_fold(1usize, |a, &d| a.checked_mul(d))
.context("tensor shape product overflows usize")?;
let byte_size = len.checked_mul(dt.size_of())
.context("tensor byte size overflows usize")?;
ensure!(byte_size == header.data_size_bytes as usize, "shape/len vs data_size_bytes mismatch");
Defense in depth: make Tensor::uninitialized_aligned_dt reject when product(shape)*size_of overflows, and add a len * size_of == storage.byte_len() invariant check in the as_slice* accessors (or at Tensor construction) so a len/storage mismatch can never reach from_raw_parts.
Mapping: CWE-190, CWE-125; mitigations align with input validation (OWASP ASVS V5) and safe integer handling (CERT INT32-C analogue).
Prior art / why this is not already fixed
eacd13ccb(2026-03-23, "Add blob-size validation to BlockQuantStorage constructors") added overflow/blob-size validation only to the block-quant path; the denseDatLoader/read_tensorpath was left unguarded. The maintainers fixed the sibling and missed this one.- PR #745 ("Fix UB by creating uninit Tensors with a non-null pointer") is a different UB (null base pointer on zero-length slices) in the same module family.
- No CVE / RustSec / GHSA / OSV / Huntr entry matches this bug; last change to
nnef/src/tensors.rspredates HEAD and added no overflow guard to the dense path.
Reported by: s1ko (s1ko@riseup.net · github.com/s1ko)
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "tract-nnef"
},
"ranges": [
{
"events": [
{
"introduced": "0.23.0"
},
{
"fixed": "0.23.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "tract-nnef"
},
"ranges": [
{
"events": [
{
"introduced": "0.22.0"
},
{
"fixed": "0.22.2"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "crates.io",
"name": "tract-nnef"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.21.16"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-55093"
],
"database_specific": {
"cwe_ids": [
"CWE-125",
"CWE-190"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-18T15:05:23Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "- **Component:** `tract-nnef` (`nnef/src/tensors.rs::read_tensor`) + `tract-data` (`data/src/tensor.rs`)\n- **Affected versions:** `\u003c 0.21.16`, `0.22.0`\u2013`0.22.2`, `0.23.0`\u2013`0.23.1` \u2014 the dense `DatLoader` path was unguarded across all three release lines; patched in 0.21.16 / 0.22.2 / 0.23.1\n- **Class:** CWE-190 (integer overflow) \u2192 CWE-125 (out-of-bounds read)\n- **Trigger:** loading a crafted NNEF model archive (`*.nnef.tgz` / `*.nnef.tar` / dir) via the public `tract_nnef::nnef().model_for_path` / `model_for_read`\n- **Impact:** `read_tensor` returns a memory-unsafe tensor (reported `len` 2^61 over a 56-byte heap allocation). Always-on primitive: a **bounded heap out-of-bounds read** during model build (`as_uniform`), an adjacent-heap information-disclosure reachable via the public load API. The resulting slice is an unsound `from_raw_parts(ptr, 2^61)` that **SIGSEGVs (DoS)** on any access past the mapped region (demonstrated by direct access). No out-of-bounds write and no RCE were achieved \u2014 tract\u0027s const-folding/`as_uniform` fast-paths fold simple consuming graphs without the full read.\n- **Severity:** Medium\n\n## Summary\n\n`read_tensor` builds a tensor `shape` from attacker-controlled 32-bit dimensions and computes the element count `len = product(shape)` and the byte allocation `product(shape) * size_of(dt)` with **unchecked `usize` arithmetic**. In `--release` (no `overflow-checks`), both products wrap modulo 2^64. An attacker chooses dimensions so that the wrapped products collapse to a small value that satisfies the header consistency check, while the *true* element count remains astronomically large. `read_tensor` returns `Ok` with a `Tensor` whose reported `len` (e.g. 2^61+7) is far larger than its backing heap allocation (e.g. 56 bytes). The unchecked slice accessor `as_slice_unchecked` (`from_raw_parts(ptr, self.len)`) then produces a slice spanning ~18 exabytes over a 56-byte buffer. The out-of-bounds read fires automatically during model build (no inference required), reachable through the default `DatLoader` resource loader.\n\n## Root cause\n\n`nnef/src/tensors.rs`, `read_tensor`:\n\n```\nlet shape: TVec\u003cusize\u003e = header.dims[0..header.rank as usize].iter().map(|d| *d as _).collect();\nlet len = shape.iter().product::\u003cusize\u003e(); // (1) unchecked, wraps\n...\n} else if header.bits_per_item != u32::MAX\n \u0026\u0026 len * (header.bits_per_item as usize / 8) != header.data_size_bytes as usize // (2) wrapped == u32\n{\n bail!(...);\n}\n...\nlet mut tensor = unsafe { Tensor::uninitialized_dt(dt, \u0026shape)? }; // (3) alloc off the same wrapped product\n...\nreader.read_exact(plain.as_bytes_mut())?; // storage-bounded read, no overflow here\nOk(tensor)\n```\n\n`data/src/tensor.rs`, `uninitialized_aligned_dt`:\n\n```\nlet bytes = shape.iter().cloned().product::\u003cusize\u003e() * dt.size_of(); // (3) wraps to the same small value\nlet storage = ... Blob::new_for_size_and_align(bytes, alignment) ...;\n...\ntensor.update_strides_and_len(); // len = product(shape), wraps, no clamp\n```\n\nThe three quantities \u2014 the consistency-check LHS `(2)`, the allocation `(3)`, and the reported `len` \u2014 are all the same wrapped `product(shape)*size_of`, so they stay mutually consistent and **the consistency check at `(2)` cannot catch the overflow**. `data_size_bytes` is a `u32`, so the attacker simply sets it to the wrapped value.\n\nCorruption sink \u2014 `data/src/tensor.rs::as_slice_unchecked` (and `data/src/tensor/plain_view.rs::as_slice_unchecked`):\n\n```\nif self.storage.byte_len() == 0 { \u0026[] }\nelse { std::slice::from_raw_parts(self.as_ptr_unchecked(), self.len()) } // len = 2^61 over a 56-byte alloc\n```\n\nThe only guard is `byte_len() == 0`. A small **non-zero** allocation defeats it and yields an unsound oversized slice.\n\n## Witness (F64)\n\n```\ndims = [33955849, 7005787, 359, 3, 3, 3] (rank 6, each \u003c= u32::MAX)\nproduct(shape)= 2_305_843_009_213_693_959 = 2^61 + 7\nbits_per_item = 64 (F64), item_type = 0, item_type_vendor = 0\ndata_size_bytes = 56 # == (2^61+7)*8 mod 2^64\n```\n\n- `len * (bits/8) mod 2^64 = (2^61+7)*8 mod 2^64 = 56 == data_size_bytes` \u2192 consistency check passes.\n- allocation = `(2^61+7)*8 mod 2^64 = 56` bytes (7 \u00d7 F64).\n- reported `len` = `2^61+7` elements.\n\nOnly the `is_copy()` numeric arms (F16/F32/F64/int, and likely the `complex` arms) are exploitable. F64 is the cleanest (`bits/8` divides evenly). The `bool`, `String`, and block-quant paths are each guarded by an independent mechanism (size_of==1 prevents byte/element divergence; `String` bails on a missing `num_traits::Zero` impl; block-quant has its own `ensure!(expected_len == data_size_bytes)` and uses non-plain `Exotic` storage).\n\n## Reachability (load-time, public API)\n\n```\nnnef().model_for_read(tar)\n -\u003e proto_model_for_read nnef/src/framework.rs:303\n -\u003e DatLoader.try_load (any *.dat) nnef/src/resource.rs:97 (default loader, framework.rs:33)\n -\u003e read_tensor -\u003e Ok(Tensor{len=2^61+7, storage=56B}) nnef/src/tensors.rs:61\n -\u003e into_typed_model -\u003e variable() fragment nnef/src/ops/nnef/deser.rs:74\n ensure!(tensor.shape() == \u0026*shape) deser.rs:122 (attacker matches shape in graph.nnef -\u003e passes)\n -\u003e Const::new -\u003e wire_node core/src/model/typed.rs:67\n -\u003e Const::output_facts core/src/ops/konst.rs:54\n -\u003e TypedFact::try_from core/src/model/fact.rs:459\n -\u003e Tensor::as_uniform -\u003e is_uniform_t::\u003cf64\u003e data/src/tensor.rs:1099\n -\u003e as_slice_unchecked::\u003cf64\u003e data/src/tensor.rs:1044\n -\u003e from_raw_parts(ptr, 2^61+7) over 56-byte buffer -\u003e OOB READ\n```\n\nNo shape-vs-storage re-validation exists anywhere on this path (`proto.validate()` checks only the AST; `Const::new` checks only `is_plain`; `check_for_access` checks only the datum type; even the *safe* `PlainView::as_slice` does `from_raw_parts(ptr, self.len)` with no length guard).\n\n## Execution (proof of concept)\n\nReproduced against the crate at the affected revision, `--release`, x86_64-linux. Three scenarios:\n\n1. **Direct `read_tensor`** \u2014 feed the crafted 128-byte header + 56-byte payload:\n - `read_tensor -\u003e Ok`, `shape=[33955849,7005787,359,3,3,3]`, `len()=2305843009213693959`, `as_bytes().len()=56`, `as_slice::\u003cf64\u003e().len()=2305843009213693959`.\n - `s[7]` (first element past the 56-byte allocation) returns `0x0000000000000041` \u2192 **heap OOB read** (adjacent-heap disclosure).\n - `s[1\u003c\u003c40]` \u2192 **SIGSEGV** (signal 11).\n2. **Public load API** \u2014 build a malicious `.nnef.tar` (`graph.nnef` with `variable(label=\u0027weights\u0027, shape=[...])` + `weights.dat`) and call `nnef().model_for_read()`:\n - returns `Ok` with one `Const` node, `out[0].fact.uniform=Some(...)`, `len()=2305843009213693959` over a 56-byte buffer \u2192 confirms `as_uniform`/`is_uniform_t`/`as_slice_unchecked` performed an **OOB read on load** (bounded over-read here because `is_uniform`\u0027s `.all()` short-circuits on the uniform `0x41` payload).\n3. **Optimized graph** \u2014 same archive but the const is consumed (`output = mul(weights, weights)`), then `into_optimized` / `run`:\n - **Does not crash.** With both a uniform (`0x41\u00d756`) and a non-uniform (`0..56`) payload, `into_optimized` const-folds `mul(const, const)` to a single node **without a full-length materialization** of the oversized const, and `run` completes. A reliable arbitrary-length crash through a *normal optimized graph* was therefore NOT demonstrated; the always-on primitive is the bounded load-time over-read (scenario 2), and the wild-slice SIGSEGV is shown via direct access (scenario 1).\n\nRunnable PoC sources are available to the maintainers on request.\n\n## Detection\n\n- **Static:** flag `*.iter().product::\u003cusize\u003e()` over externally-controlled dimensions without `checked_*`/`try_into`, especially when the result feeds an allocation and a separately-tracked `len`.\n- **Runtime / fleet:** crash telemetry showing SIGSEGV inside `is_uniform_t` / `from_raw_parts` during NNEF model load; an ASAN build flags `heap-buffer-overflow READ` in `read_tensor`\u2192`as_uniform`.\n- **Input filter (compensating):** reject NNEF `.dat` tensors where `product(dims)` overflows `u64`, or where `product(dims) * size_of(dt) != data_size_bytes` computed in **checked** arithmetic, before constructing the tensor.\n- **YARA-ish heuristic for `.dat` blobs:** NNEF magic `4E EF 01 00`, `rank\u003c=8`, and any `dim \u003e= 0x10000` whose checked product with the others overflows.\n\n## Mitigation (suggested fix)\n\nIn `read_tensor`, compute the element count and byte size with checked arithmetic and reject on overflow, mirroring the guard already present on the block-quant path (`ensure!(expected_len == data_size_bytes)` added in `eacd13ccb`):\n\n```\nlet len = shape.iter().try_fold(1usize, |a, \u0026d| a.checked_mul(d))\n .context(\"tensor shape product overflows usize\")?;\nlet byte_size = len.checked_mul(dt.size_of())\n .context(\"tensor byte size overflows usize\")?;\nensure!(byte_size == header.data_size_bytes as usize, \"shape/len vs data_size_bytes mismatch\");\n```\n\nDefense in depth: make `Tensor::uninitialized_aligned_dt` reject when `product(shape)*size_of` overflows, and add a `len * size_of == storage.byte_len()` invariant check in the `as_slice*` accessors (or at `Tensor` construction) so a `len`/storage mismatch can never reach `from_raw_parts`.\n\nMapping: CWE-190, CWE-125; mitigations align with input validation (OWASP ASVS V5) and safe integer handling (CERT INT32-C analogue).\n\n## Prior art / why this is not already fixed\n\n- `eacd13ccb` (2026-03-23, \"Add blob-size validation to BlockQuantStorage constructors\") added overflow/blob-size validation **only to the block-quant path**; the dense `DatLoader`/`read_tensor` path was left unguarded. The maintainers fixed the sibling and missed this one.\n- PR #745 (\"Fix UB by creating uninit Tensors with a non-null pointer\") is a *different* UB (null base pointer on zero-length slices) in the same module family.\n- No CVE / RustSec / GHSA / OSV / Huntr entry matches this bug; last change to `nnef/src/tensors.rs` predates HEAD and added no overflow guard to the dense path.\n\n---\n\nReported by: s1ko (s1ko@riseup.net \u00b7 github.com/s1ko)",
"id": "GHSA-x5mv-8wgw-29hg",
"modified": "2026-06-18T15:05:23Z",
"published": "2026-06-18T15:05:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/sonos/tract/security/advisories/GHSA-x5mv-8wgw-29hg"
},
{
"type": "PACKAGE",
"url": "https://github.com/sonos/tract"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "tract-nnef: integer overflow in NNEF `.dat` tensor parser yields an out-of-bounds read on model load"
}
GHSA-X5PQ-PM4R-VX73
Vulnerability from github – Published: 2022-05-24 19:02 – Updated: 2022-08-06 00:00A flaw was found in libwebp in versions before 1.0.1. An out-of-bounds read was found in function WebPMuxCreateInternal. The highest threat from this vulnerability is to data confidentiality and to the service availability.
{
"affected": [],
"aliases": [
"CVE-2018-25012"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-05-21T17:15:00Z",
"severity": "CRITICAL"
},
"details": "A flaw was found in libwebp in versions before 1.0.1. An out-of-bounds read was found in function WebPMuxCreateInternal. The highest threat from this vulnerability is to data confidentiality and to the service availability.",
"id": "GHSA-x5pq-pm4r-vx73",
"modified": "2022-08-06T00:00:44Z",
"published": "2022-05-24T19:02:56Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-25012"
},
{
"type": "WEB",
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9123"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=1956922"
},
{
"type": "WEB",
"url": "https://chromium.googlesource.com/webm/libwebp/+/95fd65070662e01cc9170c4444f5c0859a710097"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2021/06/msg00005.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2021/06/msg00006.html"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20211112-0001"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-X5PR-3426-W9PH
Vulnerability from github – Published: 2025-08-22 18:31 – Updated: 2026-01-07 18:30In the Linux kernel, the following vulnerability has been resolved:
f2fs: fix to avoid out-of-boundary access in devs.path
- touch /mnt/f2fs/012345678901234567890123456789012345678901234567890123
- truncate -s $((102410241024)) \ /mnt/f2fs/012345678901234567890123456789012345678901234567890123
- touch /mnt/f2fs/file
- truncate -s $((102410241024)) /mnt/f2fs/file
- mkfs.f2fs /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \ -c /mnt/f2fs/file
- mount /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \ /mnt/f2fs/loop
[16937.192225] F2FS-fs (loop0): Mount Device [ 0]: /mnt/f2fs/012345678901234567890123456789012345678901234567890123\xff\x01, 511, 0 - 3ffff [16937.192268] F2FS-fs (loop0): Failed to find devices
If device path length equals to MAX_PATH_LEN, sbi->devs.path[] may not end up w/ null character due to path array is fully filled, So accidently, fields locate after path[] may be treated as part of device path, result in parsing wrong device path.
struct f2fs_dev_info { ... char path[MAX_PATH_LEN]; ... };
Let's add one byte space for sbi->devs.path[] to store null character of device path string.
{
"affected": [],
"aliases": [
"CVE-2025-38652"
],
"database_specific": {
"cwe_ids": [
"CWE-125"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-22T16:15:40Z",
"severity": "HIGH"
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nf2fs: fix to avoid out-of-boundary access in devs.path\n\n- touch /mnt/f2fs/012345678901234567890123456789012345678901234567890123\n- truncate -s $((1024*1024*1024)) \\\n /mnt/f2fs/012345678901234567890123456789012345678901234567890123\n- touch /mnt/f2fs/file\n- truncate -s $((1024*1024*1024)) /mnt/f2fs/file\n- mkfs.f2fs /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \\\n -c /mnt/f2fs/file\n- mount /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \\\n /mnt/f2fs/loop\n\n[16937.192225] F2FS-fs (loop0): Mount Device [ 0]: /mnt/f2fs/012345678901234567890123456789012345678901234567890123\\xff\\x01, 511, 0 - 3ffff\n[16937.192268] F2FS-fs (loop0): Failed to find devices\n\nIf device path length equals to MAX_PATH_LEN, sbi-\u003edevs.path[] may\nnot end up w/ null character due to path array is fully filled, So\naccidently, fields locate after path[] may be treated as part of\ndevice path, result in parsing wrong device path.\n\nstruct f2fs_dev_info {\n...\n\tchar path[MAX_PATH_LEN];\n...\n};\n\nLet\u0027s add one byte space for sbi-\u003edevs.path[] to store null\ncharacter of device path string.",
"id": "GHSA-x5pr-3426-w9ph",
"modified": "2026-01-07T18:30:21Z",
"published": "2025-08-22T18:31:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-38652"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/1b1efa5f0e878745e94a98022e8edc675a87d78e"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/1cf1ff15f262e8baf12201b270b6a79f9d119b2d"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/345fc8d1838f3f8be7c8ed08d86a13dedef67136"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/3466721f06edff834f99d9f49f23eabc6b2cb78e"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/5661998536af52848cc4d52a377e90368196edea"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/666b7cf6ac9aa074b8319a2b68cba7f2c30023f0"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/70849d33130a2cf1d6010069ed200669c8651fbd"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/755427093e4294ac111c3f9e40d53f681a0fbdaa"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/dc0172c74bd9edaee7bea2ebb35f3dbd37a8ae80"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2025/10/msg00007.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2025/10/msg00008.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H",
"type": "CVSS_V3"
}
]
}
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
- To reduce the likelihood of introducing an out-of-bounds read, ensure that you validate and ensure correct calculations for any length argument, buffer size calculation, or offset. Be especially careful of relying on a sentinel (i.e. special character such as NUL) in untrusted inputs.
Mitigation
Strategy: Language Selection
Use a language that provides appropriate memory abstractions.
CAPEC-540: Overread Buffers
An adversary attacks a target by providing input that causes an application to read beyond the boundary of a defined buffer. This typically occurs when a value influencing where to start or stop reading is set to reflect positions outside of the valid memory location of the buffer. This type of attack may result in exposure of sensitive information, a system crash, or arbitrary code execution.