Downloads · 30 days
0
ericblackgachara/caffe-truncation-poc
caffe-truncation-poc is a machine learning model from ericblackgachara. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
The copy loop in FromProto() is bounded by count (not proto.datasize()), and a CHECKEQ(count, proto.datasize()) guard fires before any write. SyncedMemory has no virtual functions (no vtable to overwrite). This is a r…
Downloads · 30 days
0
Access
Public
Updated May 10, 2026
Repo size
117 KB
Likes
0
Public
Click a slice to open those files.
.pdf117 KB · 92%
From the Hugging Face model README
The copy loop in FromProto() is bounded by count_ (not proto.data_size()),
and a CHECK_EQ(count_, proto.data_size()) guard fires before any write.
SyncedMemory has no virtual functions (no vtable to overwrite).
This is a real bug with real impact, but severity is Medium, not Critical.
.caffemodel (protobuf)BlobShape.dim is declared as int64 in caffe.proto but cast to int32 at:
src/caffe/blob.cpp:40 — shape_vec[i] = shape.dim(i) (no range check)src/caffe/blob.cpp:298 — shape[i] = proto.shape().dim(i) (no range check)A dim value of 0x100000001 (int64) truncates to 1 (int32) → count_ = 1.
Set dim = 0x100000001 (truncates to 1) + data[] with >1 entries.
CHECK_EQ(count_=1, proto.data_size()=N) → LOG(FATAL) → process abort.
Attacker controls WHEN Caffe crashes by controlling data count.
Set dim = 0x100000001 (truncates to 1) + exactly 1 data entry.
CHECK_EQ(1, 1) passes. Blob accepted with shape [1] when it should be [4294967297].
Model that expects a 4B-element tensor operates on a 1-element blob.
Impact: adversarial inference manipulation / silent wrong-model behavior.
// FromProto() — blob.cpp:315-320
CHECK_EQ(count_, proto.data_size()); // ABORTS if mismatch
for (int i = 0; i < count_; ++i) { // bounded by count_, not proto.data_size()
data_vec[i] = proto.data(i); // only writes count_ elements
}
The CHECK guard fires before any write. Loop uses count_, not proto.data_size().
SyncedMemory has no virtual functions. No vtable overwrite possible.
| File | Line | Issue |
|---|---|---|
src/caffe/blob.cpp | 40 | shape_vec[i] = shape.dim(i) — int64→int32, no range check |
src/caffe/blob.cpp | 298 | shape[i] = proto.shape().dim(i) — same in FromProto |
src/caffe/proto/caffe.proto | BlobShape | repeated int64 dim consumed as int32 |
poc_caffe_truncation.py — demonstrates both DoS and silent corruption effectspython poc_caffe_truncation.py dos # controlled process abort
python poc_caffe_truncation.py corrupt # silent shape corruption
// blob.cpp — Reshape(const BlobShape& shape):
for (int i = 0; i < shape.dim_size(); ++i) {
CHECK_LE(shape.dim(i), INT_MAX) << "BlobShape dim exceeds INT_MAX";
CHECK_GE(shape.dim(i), 0) << "BlobShape dim is negative";
shape_vec[i] = static_cast<int>(shape.dim(i));
}
Submit this SEPARATELY from caffe-oom-poc (the INT_MAX boundary case OOM bug). These are distinct vulnerabilities with different root causes and effects.