Views
No views yet
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)0x100000001 (int64) truncates to 1 (int32) → count_ = 1.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.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.1// FromProto() — blob.cpp:315-320
2CHECK_EQ(count_, proto.data_size()); // ABORTS if mismatch
3for (int i = 0; i < count_; ++i) { // bounded by count_, not proto.data_size()
4 data_vec[i] = proto.data(i); // only writes count_ elements
5}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 effects1python poc_caffe_truncation.py dos # controlled process abort
2python poc_caffe_truncation.py corrupt # silent shape corruption1// blob.cpp — Reshape(const BlobShape& shape):
2for (int i = 0; i < shape.dim_size(); ++i) {
3 CHECK_LE(shape.dim(i), INT_MAX) << "BlobShape dim exceeds INT_MAX";
4 CHECK_GE(shape.dim(i), 0) << "BlobShape dim is negative";
5 shape_vec[i] = static_cast<int>(shape.dim(i));
6}