Closed
Description
Describe the bug
When compiling the following code with any erlc from OTP 24.3.x (tested with 24.3.4.17) the resulting .beam file reports corrupted binary padding when executed on an x86_64 linux machine with either of OTP24/OTP25/OTP26/OTP27
To Reproduce
Save the attached erlang code as binary_error.erl and execute the corruption demo:
# Using OTP24 on linux x86_64
erlc binary_error.erl
# Using either of OTP24/25/26/27
erl -eval "binary_error:demo()"
Erlang/OTP 24 [erts-12.3.2.17] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit]
Eshell V12.3.2.17 (abort with ^G)
1> Error <<0,0,0,0,0,0,0,0,0,0,0,0,191,26,214,52,25,183,242,40,245,124,0,0,232,0,
0,0,0,0,0,0>> != <<0,0,0,0,0,0,0,0,0,0,0,0,46,39,82,188,226,30,28,247,
217,209,255,170,91,199,135,225,44,86,233,52>>
...<snip>...
Done found 37 errors in 10000 iterations
Using the same OTP24 pre compiled .beam file with OTP27 (27.0.1):
$ erl -eval "binary_error:demo()"
Erlang/OTP 27 [erts-15.0.1] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]
Error <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,85,9,16,144,126,0,0,128,0,0,0,0,0,0,
0>> != <<0,0,0,0,0,0,0,0,0,0,0,0,103,31,112,17,76,235,1,188,119,220,82,
93,146,95,157,20,149,76,19,28>>
...<snip>...
Done found 63 errors in 10000 iterations
Expected behavior
It is expected that the padding result of <<0:96/unsigned-integer, Hash:20/binary>>
always retains the same 20 bytes of Hash
as postfix.
Affected versions
Compiler of OTP24 (24.3.4.17) is causing this issue.
Runtimes of OTP24/25/26/27 are all affected if the compiled .beam file of OTP24 is used.
Additional context
binary_error.erl
-module(binary_error).
-export([demo/0]).
to_bytes32(Hash = <<_:160/unsigned-integer>>) ->
<<0:96/unsigned-integer, Hash:20/binary>>.
prefix() ->
<<0:96>>.
process() ->
Bin = rand:bytes(20),
Padded = to_bytes32(Bin),
case Padded =:= <<(prefix())/binary, Bin/binary>> of
false ->
io:format("Error ~p != ~p~n", [Padded, <<(prefix())/binary, Bin/binary>>]),
1;
true ->
0
end.
demo() ->
Iters = 10000,
Errors = lists:sum([process() || _ <- lists:seq(1, Iters)]),
io:format("Done found ~p errors in ~p iterations ~n", [Errors, Iters]).