# CoreML (apple/coremltools) MILBlob Span::Slice integer-overflow bounds-check bypass -> OOB read PoC package for a heap/mapped out-of-bounds read in the CoreML weight-blob parser (`MILBlob`) shipped in `apple/coremltools`. A crafted `.mlmodelc` / `weights.bin` weight-blob file with attacker-controlled `blob_metadata.offset` and `blob_metadata.sizeInBytes` (both `uint64`) triggers a 64-bit integer overflow in the bounds check inside `Span::Slice(index, size)`, returning a `Span` whose `Size()` is enormous (here `2^64 - 50`). A consumer reading the weight bytes then reads far past the mapped file. ## Files - `weights.bin` - the malicious CoreML weight-blob file (384 bytes) - `craft.py` - script that generates `weights.bin` (documents the byte layout) - `harness.cpp` - ASan harness that drives the REAL `StorageReader` / `MMapFileReader` / `Span` - `build.sh` - build command (clang++ + ASan) - `asan_crash.txt` - the captured AddressSanitizer crash trace ## Reproduce git clone --filter=blob:none --sparse https://github.com/apple/coremltools.git cd coremltools git sparse-checkout set mlmodel/src/MILBlob # commit pinned for this PoC: 3fb88603a6af3d12bf72ca2dcc0a3724a631317b clang++ -std=c++17 -fsanitize=address -g -O0 -Imlmodel/src \ harness.cpp \ mlmodel/src/MILBlob/Blob/StorageReader.cpp \ mlmodel/src/MILBlob/Blob/MMapFileReader.cpp \ mlmodel/src/MILBlob/Blob/MMapFileReaderFactory.cpp \ -o harness python3 craft.py ASAN_OPTIONS=detect_leaks=0 ./harness weights.bin ## Root cause `mlmodel/src/MILBlob/Util/Span.hpp` (~line 325): Span Slice(size_t index, size_t size) const { MILVerifyIsTrue(size > 0 && index < Size() && index + size <= Size(), std::range_error, "index out of bounds"); return Span(Data() + index, size); } `index + size` is an unchecked 64-bit addition. With `index = 100` and `size = 2^64 - 50`, `index + size` wraps to `50`, which is `<= Size()`, so the check passes and an oversized `Span` is returned. Both operands are attacker-controlled: `StorageReader::Impl::GetRawDataView` (`StorageReader.cpp`) calls `m_reader->ReadData(metadata.offset, metadata.sizeInBytes)`, and `MMapFileReader::ReadData` (`MMapFileReader.cpp`) forwards straight to `m_dataSpan.Slice(offset, length)`. The only validation on the metadata is the `sentinel == 0xDEADBEEF` check in `GetMetadata` - `offset` and `sizeInBytes` are never range-checked before reaching `Slice`. ## Source availability 100% open source, BSD-3-Clause: https://github.com/apple/coremltools Vulnerable file: `mlmodel/src/MILBlob/Util/Span.hpp`.