Impact
A crafted External Term Format (ETF) payload of just 7 bytes crashes the BEAM virtual machine when decoded by binary_to_term/1,2:
binary_to_term(<<131,$M,0:32,0>>).
The BIT_BINARY_EXT tag (77) with Len=0 and Bits=0 passes the existing validation in the ETF decoder (erts/emulator/beam/external.c) but triggers an unsigned integer underflow when computing the bitstring
size. The resulting value (~2^64) is used as a memory allocation size, which immediately crashes the VM with:
binary_alloc: Cannot allocate 2305843009213693951 bytes of memory (of type "binary").
This is a full VM crash — not a process-level exception. OTP supervision trees, the [safe] option to binary_to_term/2, and all other Erlang-level error handling cannot intercept it.
Any application that calls binary_to_term/1,2 or enif_binary_to_term() on data from an untrusted source is vulnerable. The Erlang distribution protocol also decodes incoming terms through the same code path; however, distribution is assumed to run only in trusted networks per the OTP Secure Coding Guidelines.
Workarounds
- Do not call
binary_to_term/1,2 on data from untrusted sources. The OTP Secure Coding Guidelines (DSG-011) recommend avoiding these functions altogether on untrusted data.
- If distribution is exposed to untrusted networks, configure it to use TLS with client certificate verification.
- Use alternative serialization formats (JSON, Protocol Buffers) for untrusted external input.
Note: the [safe] option to binary_to_term/2 does NOT protect against this crash. It only restricts atom creation, not structural validation of binary encodings.
Affected/Unaffected Versions
A version larger than or equal to one of the listed patched versions is unaffected; otherwise, a version that satisfies an expression listed
under affected versions is affected, and if it does not, it is unaffected.
The documentation of the OTP version scheme
describes how versions should be compared. Note that versions used prior to OTP 17.0, when the new OTP version scheme was introduced, are never listed since it is not well defined how to compare those versions.
In the case of this vulnerability, versions prior to OTP 27.0 are unaffected (the vulnerable code path was introduced in OTP 27.0).
Credits
Thanks to Paul Guyot for finding and responsibly disclosing this vulnerability to the Erlang/OTP project.
Impact
A crafted External Term Format (ETF) payload of just 7 bytes crashes the BEAM virtual machine when decoded by
binary_to_term/1,2:The BIT_BINARY_EXT tag (77) with
Len=0andBits=0passes the existing validation in the ETF decoder (erts/emulator/beam/external.c) but triggers an unsigned integer underflow when computing the bitstringsize. The resulting value (~2^64) is used as a memory allocation size, which immediately crashes the VM with:
This is a full VM crash — not a process-level exception. OTP supervision trees, the
[safe]option tobinary_to_term/2, and all other Erlang-level error handling cannot intercept it.Any application that calls
binary_to_term/1,2orenif_binary_to_term()on data from an untrusted source is vulnerable. The Erlang distribution protocol also decodes incoming terms through the same code path; however, distribution is assumed to run only in trusted networks per the OTP Secure Coding Guidelines.Workarounds
binary_to_term/1,2on data from untrusted sources. The OTP Secure Coding Guidelines (DSG-011) recommend avoiding these functions altogether on untrusted data.Note: the
[safe]option tobinary_to_term/2does NOT protect against this crash. It only restricts atom creation, not structural validation of binary encodings.Affected/Unaffected Versions
A version larger than or equal to one of the listed patched versions is unaffected; otherwise, a version that satisfies an expression listed
under affected versions is affected, and if it does not, it is unaffected.
The documentation of the OTP version scheme
describes how versions should be compared. Note that versions used prior to OTP 17.0, when the new OTP version scheme was introduced, are never listed since it is not well defined how to compare those versions.
In the case of this vulnerability, versions prior to OTP 27.0 are unaffected (the vulnerable code path was introduced in OTP 27.0).
Credits
Thanks to Paul Guyot for finding and responsibly disclosing this vulnerability to the Erlang/OTP project.