aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erl.xml27
-rw-r--r--erts/doc/src/erl_dist_protocol.xml11
-rw-r--r--erts/emulator/test/nif_SUITE.erl45
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c31
-rw-r--r--erts/etc/unix/etp-commands.in32
5 files changed, 123 insertions, 23 deletions
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index e1aa5ce76e..8b152b83f5 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -379,6 +379,16 @@
<c><![CDATA[Host]]></c> is the fully qualified host name of the
current host. For short names, use flag <c><![CDATA[-sname]]></c>
instead.</p>
+ <warning>
+ <p>
+ Starting a distributed node without also specifying
+ <seealso marker="#proto_dist"><c>-proto_dist inet_tls</c></seealso>
+ will expose the node to attacks that may give the attacker
+ complete access to the node and in extension the cluster.
+ When using un-secure distributed nodes, make sure that the
+ network is configured to keep potential attackers out.
+ </p>
+ </warning>
</item>
<tag><c><![CDATA[-noinput]]></c></tag>
<item>
@@ -428,12 +438,17 @@
</item>
<tag><c><![CDATA[-proto_dist Proto]]></c></tag>
<item>
+ <marker id="proto_dist"/>
<p>Specifies a protocol for Erlang distribution:</p>
<taglist>
<tag><c>inet_tcp</c></tag>
<item>TCP over IPv4 (the default)</item>
<tag><c>inet_tls</c></tag>
- <item>Distribution over TLS/SSL</item>
+ <item>Distribution over TLS/SSL, See the
+ <seealso marker="ssl:ssl_distribution">
+ Using SSL for Erlang Distribution</seealso> User's Guide
+ for details on how to setup a secure distributed node.
+ </item>
<tag><c>inet6_tcp</c></tag>
<item>TCP over IPv6</item>
</taglist>
@@ -497,6 +512,16 @@
exist between nodes running with flag <c><![CDATA[-sname]]></c>
and those running with flag <c><![CDATA[-name]]></c>, as node
names must be unique in distributed Erlang systems.</p>
+ <warning>
+ <p>
+ Starting a distributed node without also specifying
+ <seealso marker="#proto_dist"><c>-proto_dist inet_tls</c></seealso>
+ will expose the node to attacks that may give the attacker
+ complete access to the node and in extension the cluster.
+ When using un-secure distributed nodes, make sure that the
+ network is configured to keep potential attackers out.
+ </p>
+ </warning>
</item>
<tag><marker id="start_epmd"/><c>-start_epmd true | false</c></tag>
<item>
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index ee74983730..8391408a2e 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -70,6 +70,17 @@
<p>The integers in all multibyte fields are in big-endian order.</p>
+ <warning>
+ <p>
+ The Erlang Distribution protocol is not by itself secure and does not
+ aim to be so. In order to get secure distribution the distributed nodes
+ should be configured to use distribution over tls.
+ See the <seealso marker="ssl:ssl_distribution">
+ Using SSL for Erlang Distribution</seealso> User's Guide
+ for details on how to setup a secure distributed node.
+ </p>
+ </warning>
+
<section>
<title>EPMD Protocol</title>
<p>The requests served by the EPMD are summarized in the following
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 1eb58699b2..f9ee96c9ca 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -488,7 +488,7 @@ select(Config) when is_list(Config) ->
%% Wait for read
eagain = read_nif(R, 3),
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref),
- [] = flush(),
+ [] = flush(0),
ok = write_nif(W, <<"hej">>),
[{select, R, Ref, ready_input}] = flush(),
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
@@ -505,7 +505,7 @@ select(Config) when is_list(Config) ->
%% Wait for write
Written = write_full(W, $a),
0 = select_nif(W,?ERL_NIF_SELECT_WRITE,W,self(),Ref),
- [] = flush(),
+ [] = flush(0),
Written = read_nif(R,byte_size(Written)),
[{select, W, Ref, ready_output}] = flush(),
@@ -515,7 +515,7 @@ select(Config) when is_list(Config) ->
[{fd_resource_stop, W_ptr, _}] = flush(),
{1, {W_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(W),
- [] = flush(),
+ [] = flush(0),
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref),
[{select, R, Ref, ready_input}] = flush(),
eof = read_nif(R,1),
@@ -540,7 +540,7 @@ select_2(Config) ->
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
- [] = flush(),
+ [] = flush(0),
ok = write_nif(W, <<"hej">>),
[{select, R, Ref2, ready_input}] = flush(),
<<"hej">> = read_nif(R, 3),
@@ -551,7 +551,7 @@ select_2(Config) ->
Papa = self(),
spawn_link(fun() ->
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
- [] = flush(),
+ [] = flush(0),
Papa ! sync,
[{select, R, Ref1, ready_input}] = flush(),
<<"hej">> = read_nif(R, 3),
@@ -560,7 +560,7 @@ select_2(Config) ->
sync = receive_any(),
ok = write_nif(W, <<"hej">>),
done = receive_any(),
- [] = flush(),
+ [] = flush(0),
check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref1)),
[{fd_resource_stop, R_ptr, _}] = flush(),
@@ -629,6 +629,15 @@ monitor_process_a(Config) ->
monitor_process_b(Config) ->
ensure_lib_loaded(Config),
+ monitor_process_b_do(false),
+ case erlang:system_info(threads) of
+ true -> monitor_process_b_do(true);
+ false -> ok
+ end,
+ ok.
+
+
+monitor_process_b_do(FromThread) ->
Pid = spawn_link(fun() ->
receive
return -> ok
@@ -637,8 +646,11 @@ monitor_process_b(Config) ->
R_ptr = alloc_monitor_resource_nif(),
{0,_} = monitor_process_nif(R_ptr, Pid, true, self()),
[R_ptr] = monitored_by(Pid),
- ok = release_resource(R_ptr),
- [] = flush(),
+ case FromThread of
+ false -> ok = release_resource(R_ptr);
+ true -> ok = release_resource_from_thread(R_ptr)
+ end,
+ [] = flush(0),
{R_ptr, _, 1} = last_resource_dtor_call(),
[] = monitored_by(Pid),
Pid ! return,
@@ -660,7 +672,7 @@ monitor_process_c(Config) ->
exit
end),
[{Pid, done, R_ptr, Mon1},
- {monitor_resource_down, R_ptr, Pid, Mon2}] = flush(),
+ {monitor_resource_down, R_ptr, Pid, Mon2}] = flush(2),
compare_monitors_nif(Mon1, Mon2),
{R_ptr, _, 1} = last_resource_dtor_call(),
ok.
@@ -708,7 +720,7 @@ demonitor_process(Config) ->
1 = demonitor_process_nif(R_ptr, MonBin2),
ok = release_resource(R_ptr),
- [] = flush(),
+ [] = flush(0),
{R_ptr, _, 1} = last_resource_dtor_call(),
[] = monitored_by(Pid),
Pid ! return,
@@ -2307,10 +2319,16 @@ receive_any(Timeout) ->
after Timeout -> timeout end.
flush() ->
- flush(10).
-flush(Timeout) ->
+ flush(1).
+
+flush(0) ->
+ flush(0, 10); % don't waste too much time waiting for nothing
+flush(N) ->
+ flush(N, 1000).
+
+flush(N, Timeout) ->
receive M ->
- [M | flush(Timeout)]
+ [M | flush(N-1)]
after Timeout ->
[]
end.
@@ -2789,6 +2807,7 @@ alloc_resource(_,_) -> ?nif_stub.
make_resource(_) -> ?nif_stub.
get_resource(_,_) -> ?nif_stub.
release_resource(_) -> ?nif_stub.
+release_resource_from_thread(_) -> ?nif_stub.
last_resource_dtor_call() -> ?nif_stub.
make_new_resource(_,_) -> ?nif_stub.
check_is(_,_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 3747291e7e..15d31162ed 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -972,6 +972,30 @@ static ERL_NIF_TERM release_resource(ErlNifEnv* env, int argc, const ERL_NIF_TER
return enif_make_atom(env,"ok");
}
+static void* threaded_release_resource(void* resource)
+{
+ enif_release_resource(resource);
+}
+
+static ERL_NIF_TERM release_resource_from_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ void* resource;
+ ErlNifTid tid;
+ int err;
+
+ if (!get_pointer(env, argv[0], &resource)) {
+ return enif_make_badarg(env);
+ }
+ if (enif_thread_create("nif_SUITE:release_resource_from_thread", &tid,
+ threaded_release_resource, resource, NULL) != 0) {
+ return enif_make_badarg(env);
+ }
+ err = enif_thread_join(tid, NULL);
+ assert(err == 0);
+ return atom_ok;
+}
+
+
/*
* argv[0] an atom
* argv[1] a binary
@@ -2537,6 +2561,7 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
static unsigned long spawn_cnt = 0;
static unsigned long kill_cnt = 0;
static unsigned long proc_histogram[FRENZY_PROCS_MAX];
+ static int initialized = 0;
static const unsigned int primes[] = {7, 13, 17, 19};
@@ -2556,7 +2581,7 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
if (enif_is_atom(env, Op)) {
if (Op == atom_init) {
- if (procs_lock || !enif_get_uint(env, Rnd, &frenzy_rand_bits_max))
+ if (initialized || !enif_get_uint(env, Rnd, &frenzy_rand_bits_max))
return enif_make_badarg(env);
procs_lock = enif_mutex_create("nif_SUITE:monitor_frenzy.procs");
@@ -2583,6 +2608,7 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
spawn_cnt = 1;
kill_cnt = 0;
+ initialized = 1;
return enif_make_uint(env, 0); /* SelfPix */
}
else if (Op == atom_stats) {
@@ -2613,7 +2639,7 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
enif_make_ulong(env, res_dtor_cnt)));
}
- else if (Op == atom_stop && procs_lock) { /* stop all */
+ else if (Op == atom_stop && initialized) { /* stop all */
/* Release all resources */
for (rix = 0; rix < FRENZY_RESOURCES_MAX; rix++) {
@@ -2903,6 +2929,7 @@ static ErlNifFunc nif_funcs[] =
{"make_resource", 1, make_resource},
{"get_resource", 2, get_resource},
{"release_resource", 1, release_resource},
+ {"release_resource_from_thread", 1, release_resource_from_thread},
{"last_resource_dtor_call", 0, last_resource_dtor_call},
{"make_new_resource", 2, make_new_resource},
{"check_is", 11, check_is},
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index fc7b614c21..8f70f879d5 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -1,3 +1,4 @@
+# -*- gdb-script -*-
#
# %CopyrightBegin%
#
@@ -2153,13 +2154,22 @@ define etp-processes
printf "No processes, since system isn't initialized!\n"
else
set $proc_ix = 0
- while $proc_ix < erts_proc.r.o.max
- set $proc = (Process *) *((UWord *) &erts_proc.r.o.tab[$proc_ix])
- if ($proc != ((Process *) 0) && $proc != &erts_invalid_process)
+ set $proc_max_ix = erts_proc.r.o.max
+ set $proc_tab = erts_proc.r.o.tab
+ set $invalid_proc = &erts_invalid_process
+ set $proc_decentile = $proc_max_ix / 10
+ set $proc_printile = $proc_decentile
+ while $proc_ix < $proc_max_ix
+ set $proc = (Process *) *((UWord *) ($proc_tab + $proc_ix))
+ if ($proc != ((Process *) 0) && $proc != $invalid_proc)
printf "---\n"
printf " Pix: %d\n", $proc_ix
etp-process-info $proc
end
+ if $proc_ix == $proc_printile
+ printf "--- %d%% (%d / %d) searched\n", $proc_printile / $proc_decentile * 10, $proc_ix, $proc_max_ix
+ set $proc_printile += $proc_decentile
+ end
set $proc_ix++
end
printf "---\n",
@@ -2479,15 +2489,19 @@ document etp-port-info
%---------------------------------------------------------------------------
end
-
define etp-ports
if (!erts_initialized)
printf "No ports, since system isn't initialized!\n"
else
set $port_ix = 0
- while $port_ix < erts_port.r.o.max
- set $port = (Port *) *((UWord *) &erts_port.r.o.tab[$port_ix])
- if ($port != ((Port *) 0) && $port != &erts_invalid_port)
+ set $port_max_ix = erts_port.r.o.max
+ set $port_tab = erts_port.r.o.tab
+ set $invalid_port = &erts_invalid_port
+ set $port_decentile = $port_max_ix / 10
+ set $port_printile = $port_decentile
+ while $port_ix < $port_max_ix
+ set $port = (Port *) *((UWord *) ($port_tab + $port_ix))
+ if ($port != ((Port *) 0) && $port != $invalid_port)
if (*(((Uint32 *) &(((Port *) $port)->state))) & 0x100) == 0
# I.e, not free
printf "---\n"
@@ -2495,6 +2509,10 @@ define etp-ports
etp-port-info $port
end
end
+ if $port_ix == $port_printile
+ printf "--- %d%% (%d / %d) searched\n", $port_printile / $port_decentile * 10, $port_ix, $port_max_ix
+ set $port_printile += $port_decentile
+ end
set $port_ix++
end
printf "---\n",