YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
PoC: OOB heap read in Caffe DataTransformer::Transform via undersized Datum.data() (CWE-125)
Loading a crafted Caffe Datum (from a LevelDB/LMDB record or a serialized Datum) whose declared
channels*height*width exceeds its data() byte string makes DataTransformer::Transform read far past
the string's heap buffer.
Root cause
src/caffe/data_transformer.cpp:53,101-109:
const string& data = datum.data();
const bool has_uint8 = data.size() > 0; // any non-empty string passes
for (c < datum_channels) for (h < height) for (w < width) {
data_index = (c * datum_height + h_off + h) * datum_width + w_off + w; // :101
if (has_uint8)
datum_element = static_cast<Dtype>(static_cast<uint8_t>(data[data_index])); // :109 OOB read
}
datum_channels/height/width come from the attacker-controlled Datum protobuf, while data is the
datum.data() byte string. The loop indexes data up to channels*height*width - 1 with no check that
data.size() >= channels*height*width. A Datum declaring channels=3,height=100,width=100 (30000
elements) but carrying a 100-byte data string reads data[100..29999] — far past the heap buffer. The
only guard (data_transformer.cpp:167-169) checks the output blob shape, never datum.data().size().
Reachable on the normal data-loading path (DataLayer -> Datum::ParseFromString -> Transform). Distinct
from the already-filed Caffe HDF5 hsize_t->int truncation bug (different parser, different sink).
Reproduce (AddressSanitizer)
g++ -fsanitize=address -g -O0 caffe_datatransformer_oob_read_harness.cpp -o poc && ./poc
# datum.data().size() = 100 ; declared channels*height*width = 30000
# Transform() indexes data[data_index] up to 29999 with no bounds check...
# ==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 ... 0 bytes after the 101-byte region
Fix
Before the transform loop, validate data.size() >= datum_channels * datum_height * datum_width (and reject
otherwise), or bound data_index against data.size().