Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core dump when decoding long list in binary_to_term/1 #6439

Closed
mikpe opened this issue Nov 6, 2022 · 0 comments
Closed

Core dump when decoding long list in binary_to_term/1 #6439

mikpe opened this issue Nov 6, 2022 · 0 comments
Assignees
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM

Comments

@mikpe
Copy link
Contributor

mikpe commented Nov 6, 2022

Describe the bug
When calling binary_to_term/1 on a binary containing the encoding of a list of length 1 bsl 30 or longer, the VM segfaults. There are three problems in the code:

  • the code stores a 32-bit unsigned length in a 32-bit signed integer, causing some valid lengths to appear negative and pointer (hp) increments by those values to yield incorrect results (this is similar to Cannot allocate 18446744071562067968 bytes on erlang:binary_to_term/1 #6393)
  • the code multiplies the length by 2 before incrementing hp by it, causing the sign flip to occur for many more valid lengths
  • the code performs this multiplication in 32-bit precision on 64-bit platforms, causing the MSB of the length to be lost

The fix requires two changes: to use an unsigned type for the length, and to perform the multiplication in a wider type.

To Reproduce

> cat bug.erl
-module(bug).
-export([test/1]).

test(N) ->
  length(binary_to_term(make(N))).

%% This is term_to_binary(lists:duplicate(N, [])) without
%% the excessive intermediate memory usage.
make(N) ->
  <<131, 108, N:4/big-unsigned-integer-unit:8, (binary:copy(<<106>>, N + 1))/binary>>.
> erl
Erlang/OTP 25 [erts-13.1.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Eshell V13.1.2  (abort with ^G)
1> c(bug).
{ok,bug}
2> bug:test(1 bsl 30).
Segmentation fault (core dumped)

Expected behavior
The call should (eventually) succeed and return 1073741824.

Affected versions
All current releases, i.e., 25.1.2, 24.3.4.6, and 23.3.4.18. I didn't check older releases.

Additional context
Once the bug is fixed the reproducer should not crash the VM, but it will require lots of memory. I've run it with 24GB RAM and 32GB swap, but the swapping was painful.

@mikpe mikpe added the bug Issue is reported as a bug label Nov 6, 2022
mikpe added a commit to mikpe/otp that referenced this issue Nov 6, 2022
- use unsigned type for the length n
- perform mutiplication by 2 in wider type

Fixes erlang#6439
@rickard-green rickard-green added the team:VM Assigned to OTP team VM label Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

3 participants