File 0352-erts-Fix-bug-in-enif_binary_to_term-for-immediates.patch of Package erlang

From d7bacbc798d608f259eb2faaaf194cb9df323018 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Tue, 15 May 2018 20:42:46 +0200
Subject: [PATCH] erts: Fix bug in enif_binary_to_term for immediates

Symptom: Heap corruption

Expanded test case to provoke this bug
and test some more term types.
---
 erts/emulator/beam/erl_nif.c                  |  6 ++++--
 erts/emulator/test/nif_SUITE.erl              | 17 ++++++++++++-----
 erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 10 +++++++---
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 479a2f4809..a41145af41 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1157,8 +1157,10 @@ size_t enif_binary_to_term(ErlNifEnv *dst_env,
     if (is_non_value(*term)) {
         return 0;
     }
-    erts_factory_close(&factory);
-    cache_env(dst_env);
+    if (size > 0) {
+        erts_factory_close(&factory);
+        cache_env(dst_env);
+    }
 
     ASSERT(bp > data);
     return bp - data;
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 9c1694fa8a..4c5109c4ac 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -2111,16 +2111,23 @@ nif_term_to_binary(Config) ->
 
 nif_binary_to_term(Config) ->
     ensure_lib_loaded(Config),
-    T = {#{ok => nok}, <<0:8096>>, lists:seq(1,100)},
+    BigMap = maps:from_list([{I,-I} || I <- lists:seq(1,100)]),
+    [nif_binary_to_term_do(T)
+     || T <- [{#{ok => nok}, <<0:8096>>, lists:seq(1,100)},
+              atom, 42, self(), BigMap]],
+    ok.
+
+nif_binary_to_term_do(T) ->
+    Dummy = [true|false],
     Bin = term_to_binary(T),
     Len = byte_size(Bin),
-    {Len,T} = binary_to_term_nif(Bin, undefined, 0),
+    {Len,T,Dummy} = binary_to_term_nif(Bin, undefined, 0),
     Len = binary_to_term_nif(Bin, self(), 0),
-    T = receive M -> M after 1000 -> timeout end,
+    {T,Dummy} = receive M -> M after 1000 -> timeout end,
 
-    {Len, T} = binary_to_term_nif(Bin, undefined, ?ERL_NIF_BIN2TERM_SAFE),
+    {Len,T,Dummy} = binary_to_term_nif(Bin, undefined, ?ERL_NIF_BIN2TERM_SAFE),
     false = binary_to_term_nif(<<131,100,0,14,"undefined_atom">>,
-			   undefined, ?ERL_NIF_BIN2TERM_SAFE),
+                               undefined, ?ERL_NIF_BIN2TERM_SAFE),
     false = binary_to_term_nif(Bin, undefined, 1),
     ok.
 
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index f2b1ef9d24..3d262913aa 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -1958,7 +1958,7 @@ static ERL_NIF_TERM term_to_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM
 static ERL_NIF_TERM binary_to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {
     ErlNifBinary bin;
-    ERL_NIF_TERM term, ret_term;
+    ERL_NIF_TERM term, dummy, ret_term;
     ErlNifPid pid;
     ErlNifEnv *msg_env = env;
     unsigned int opts;
@@ -1971,6 +1971,9 @@ static ERL_NIF_TERM binary_to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM
 	|| !enif_get_uint(env, argv[2], &opts))
         return enif_make_badarg(env);
 
+    /* build dummy heap term first to provoke OTP-15080 */
+    dummy = enif_make_list_cell(msg_env, atom_true, atom_false);
+
     ret = enif_binary_to_term(msg_env, bin.data, bin.size, &term,
 			      (ErlNifBinaryToTerm)opts);
     if (!ret)
@@ -1978,11 +1981,12 @@ static ERL_NIF_TERM binary_to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM
 
     ret_term = enif_make_uint64(env, ret);
     if (msg_env != env) {
-        enif_send(env, &pid, msg_env, term);
+        enif_send(env, &pid, msg_env,
+                  enif_make_tuple2(msg_env, term, dummy));
         enif_free_env(msg_env);
         return ret_term;
     } else {
-        return enif_make_tuple2(env, ret_term, term);
+        return enif_make_tuple3(env, ret_term, term, dummy);
     }
 }
 
-- 
2.16.3

openSUSE Build Service is sponsored by