| |
| """Byte-level annotation of poc_oob_read_missing_verifier.ptd (64 bytes). |
| Run: python3 decode_poc.py poc_oob_read_missing_verifier.ptd |
| """ |
| import struct |
| import sys |
|
|
| with open(sys.argv[1] if len(sys.argv) > 1 else "poc_oob_read_missing_verifier.ptd", "rb") as f: |
| data = f.read() |
|
|
| assert len(data) == 64, f"expected 64 bytes, got {len(data)}" |
|
|
| root_offset = struct.unpack_from("<I", data, 0)[0] |
| fb_identifier = data[4:8] |
| fh_magic = data[8:12] |
| header_len = struct.unpack_from("<I", data, 12)[0] |
| fb_offset = struct.unpack_from("<Q", data, 16)[0] |
| fb_size = struct.unpack_from("<Q", data, 24)[0] |
| seg_base = struct.unpack_from("<Q", data, 32)[0] |
| seg_size = struct.unpack_from("<Q", data, 40)[0] |
|
|
| print(f"[0:4] root_offset (of the inner flatbuffer payload) = {root_offset} (0x{root_offset:x})") |
| print(f"[4:8] flatbuffer file_identifier = {fb_identifier!r}") |
| print(f"[8:12] FlatTensorHeader magic = {fh_magic!r}") |
| print(f"[12:16] FlatTensorHeader.length = {header_len}") |
| print(f"[16:24] FlatTensorHeader.flatbuffer_offset = {fb_offset}") |
| print(f"[24:32] FlatTensorHeader.flatbuffer_size = {fb_size}") |
| print(f"[32:40] FlatTensorHeader.segment_base_offset = {seg_base}") |
| print(f"[40:48] FlatTensorHeader.segment_data_size = {seg_size}") |
| print(f"[48:64] trailing bytes (unused padding/garbage) = {data[48:64].hex()}") |
| print() |
| loaded_flatbuffer_len = fb_offset + fb_size |
| print(f"Loaded flatbuffer segment length = flatbuffer_offset + flatbuffer_size = {fb_offset} + {fb_size} = {loaded_flatbuffer_len} bytes") |
| print(f"Root table offset stored in the file = {root_offset}") |
| if root_offset > loaded_flatbuffer_len: |
| print(f"*** root_offset ({root_offset}) EXCEEDS the loaded flatbuffer segment length ({loaded_flatbuffer_len}) ***") |
| print("This is the corrupted field that FlatTensorDataMap::load() never validates:") |
| print("no flatbuffers::Verifier runs, so GetFlatTensor()/field accessors trust this") |
| print("out-of-range offset and walk memory past the end of the loaded buffer.") |
|
|