PyTorch Mobile FlatBuffer loader: unguarded get_module_info_from_flatbuffer() SIGSEGV on malformed .ptl bytes
Target: github.com/pytorch/pytorch β torch/csrc/jit/mobile/flatbuffer_loader.cpp, C++ function get_module_info_from_flatbuffer(), exposed to Python as torch._C._get_module_info_from_flatbuffer() and reachable from the public, documented torch.jit._serialization.get_flatbuffer_module_info().
Verified against: torch==2.12.1+cpu (official CPU wheel), reproduced 5/5 runs.
Summary
get_module_info_from_flatbuffer() calls mobile::serialization::GetMutableModule() directly on caller-supplied bytes with no flatbuffers::Verifier check, and not even the basic magic-identifier check (ModuleBufferHasIdentifier) that its own sibling function performs. It then immediately starts walking the "module" as a real FlatBuffers table (ivalues, functions, operators, type_annotations), reading offsets computed from whatever garbage bytes happen to be present. On arbitrary bytes this reaches an unmapped page almost immediately, crashing the process with SIGSEGV.
The sibling function _get_model_bytecode_version_from_buffer() (backing torch.jit.get_bytecode_version_from_bytes(), same C++ file) does have the ModuleBufferHasIdentifier() check and raises a clean RuntimeError: Unrecognized data format on the identical bytes β proving the missing check, not any unrelated environmental issue, is the cause of the crash.
PoC
108 bytes of pure garbage (b"NOTVALID" + b"\x00" * 100) β no valid FlatBuffers identifier, no real structure at all.
import subprocess, sys
GARBAGE = b"NOTVALID" + b"\x00" * 100
# control: sibling function, HAS the identifier check
subprocess.run([sys.executable, "-c", f"""
import torch
torch._C._get_model_bytecode_version_from_buffer({GARBAGE!r})
"""])
# -> clean RuntimeError: Unrecognized data format, exit code 0
# vuln: unguarded function, identical bytes
subprocess.run([sys.executable, "-c", f"""
import torch
torch._C._get_module_info_from_flatbuffer({GARBAGE!r})
"""])
# -> killed by SIGSEGV, exit code -11
Observed (this environment, 5 consecutive runs)
[control] exit: 0
[control] clean exception (expected): RuntimeError: Unrecognized data format
[VULN run 0] exit: -11
[VULN run 1] exit: -11
[VULN run 2] exit: -11
[VULN run 3] exit: -11
[VULN run 4] exit: -11
5/5 reliable SIGSEGV, same input the sibling function safely rejects.
Impact
Denial of service. Any application calling torch.jit._serialization.get_flatbuffer_module_info() (or the underlying torch._C._get_module_info_from_flatbuffer()) on an untrusted or malformed .ptl file β e.g. a model inspection/introspection tool, a CI gate that reports metadata about uploaded mobile models before fully loading them β crashes the host process on a 108-byte file with no valid structure required. This is a native SIGSEGV, not a catchable Python exception.
Fix suggestion
Add the same ModuleBufferHasIdentifier() check (and/or a flatbuffers::Verifier pass) to get_module_info_from_flatbuffer() that its sibling get_bytecode_version_from_buffer() already performs, before walking the buffer as a FlatBuffers table.
Files
poc_fixed.pyβ corrected, working reproduction (the original draft PoC had an f-string escaping bug that made the subprocess code fail withSyntaxErrorbefore reaching the actual test β fixed here to run 5 real trials).
Dedup
Web-searched pytorch/pytorch for prior flatbuffer-loader segfault reports. Found pytorch/pytorch#109793 ("Segmentation fault in flatbuffer_loader.cpp:298"), closed, but that report is about a different function: parseModule() (reached via parse_and_initialize_mobile_module_for_jit(), the actual model-loading path used by torch.jit.load()), crashing on a null-pointer deref reading an ObjectType vector. This finding is about get_module_info_from_flatbuffer() (an introspection-only path, not full model loading) missing the same identifier/verifier check its sibling function has. Same general theme (missing FlatBuffers validation in this file) and same file, but a distinct function/call path and a distinct immediate crash site β flagging this relationship explicitly since a triager may consider it part of the same root-cause family rather than a fully independent bug. No report specifically naming get_module_info_from_flatbuffer or ModuleBufferHasIdentifier found.