Views
No views yet
torch.load() attempt to use weights_only=True, but the except fallback still uses weights_only=False.weights_only=True attempt (e.g., using blocked globals) and the fallback loads it unsafely.deserialize_torch_artifact() in torch/_export/serde/serialize.py:422-445 first tries weights_only=True, and on any exception falls back to weights_only=False:1try:
2 artifact = torch.load(buffer, weights_only=True) # line 437
3except Exception as e:
4 buffer.seek(0)
5 artifact = torch.load(buffer, weights_only=False) # line 440 – FALLBACK!data/sample_inputs/model.pt in a .pt2 archive that references os.system (blocklisted). The weights_only=True path fails → falls back to weights_only=False → standard pickle.load() executes the payload.weights_only=False, torch.load() calls _legacy_load() which does pickle_module.load(f) at serialization.py:1887 — this is a full unpickling operation that executes the malicious pickle before checking the magic number.torch.export.load("malicious.pt2") gets RCE. This is a separate code path from the weights loading RCE in _package.py:877.python poc_serialize_fallback.py --cmd "echo PWNED" --test-load[!] weights_only=True → Exception → weights_only=False
[!] Post-exploitation error: RuntimeError: ...PWNED output).data/sample_inputs/model.pt with pickle using GLOBAL os systemtorch.export.load() → deserialize_torch_artifact() → try weights_only=True → blockedweights_only=False → _legacy_load → pickle.load() → RCE| File | Purpose |
|---|---|
poc_serialize_fallback.py | Exploit PoC – generate & test malicious .pt2 |
torch/_export/serde/serialize.py:437-440 – Fallback to weights_only=Falsetorch/serialization.py:1887 – pickle_module.load() executes before magic check