EnigmaConsultant's picture
Upload folder using huggingface_hub
e4c8dd7 verified
|
Raw
History Blame Contribute Delete
2.67 kB
# 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<T>::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<T> 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<T>(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`.