summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngela Anderton Andin <ingela@erlang.org>2020-05-28 11:01:00 +0200
committerIngela Anderton Andin <ingela@erlang.org>2020-06-11 10:18:21 +0200
commit5a9a2fe727ba43bd6352552d42db85255b4fd4ff (patch)
tree94a7ea39e095c92f1542cca177a0be67da6c69c9
parent6d5a5f31c36bbdaad21585d25974177bd1b75e66 (diff)
downloaderlang-5a9a2fe727ba43bd6352552d42db85255b4fd4ff.tar.gz
ssl: Avoid possible sending an active message to a passive socket
In the corner case that a passive socket is started and ssl:recv never is called and the other side closes the socket, an active close message could incorrectly be sent to a passive socket.
-rw-r--r--lib/ssl/src/ssl_connection.erl8
-rw-r--r--lib/ssl/test/ssl_api_SUITE.erl34
2 files changed, 38 insertions, 4 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 8e2e794280..e1a0ce9079 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -2981,11 +2981,11 @@ header(N, Binary) ->
send_or_reply(false, _Pid, From, Data) when From =/= undefined ->
gen_statem:reply(From, Data);
-%% Can happen when handling own alert or tcp error/close and there is
-%% no outstanding gen_fsm sync events
-send_or_reply(false, no_pid, _, _) ->
+send_or_reply(false, Pid, undefined, _) when is_pid(Pid) ->
ok;
-send_or_reply(_, Pid, _From, Data) ->
+send_or_reply(_, no_pid, _, _) ->
+ ok;
+send_or_reply(_, Pid, _, Data) ->
send_user(Pid, Data).
send_user(Pid, Msg) ->
diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl
index b393ba2f9b..29d1fe6a0d 100644
--- a/lib/ssl/test/ssl_api_SUITE.erl
+++ b/lib/ssl/test/ssl_api_SUITE.erl
@@ -87,6 +87,7 @@ gen_api_tests() ->
recv_active,
recv_active_once,
recv_active_n,
+ recv_no_active_msg,
recv_timeout,
recv_close,
controlling_process,
@@ -824,6 +825,10 @@ listen_socket(Config) ->
ok = ssl:close(ListenSocket).
%%--------------------------------------------------------------------
+
+
+%%--------------------------------------------------------------------
+
recv_active() ->
[{doc,"Test recv on active socket"}].
@@ -951,6 +956,27 @@ recv_close(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok).
+%%--------------------------------------------------------------------
+recv_no_active_msg() ->
+ [{doc,"If we have a passive socket and do not call recv and peer closes we should no get"
+ "receive an active message"}].
+recv_no_active_msg(Config) when is_list(Config) ->
+ ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
+ ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, no_recv_no_active, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, ClientOpts}]),
+ ssl_test_lib:close(Client),
+ ssl_test_lib:check_result(Server, ok).
%%--------------------------------------------------------------------
controlling_process() ->
@@ -2142,6 +2168,14 @@ run_error_server([ Pid | Opts]) ->
run_client_error([Port, Opts]) ->
ssl:connect("localhost", Port, Opts).
+no_recv_no_active(Socket) ->
+ receive
+ {ssl_closed, Socket} ->
+ ct:fail(received_active_msg)
+ after 5000 ->
+ ok
+ end.
+
honor_cipher_order(Config, Honor, ServerCiphers, ClientCiphers, Expected) ->
ClientOpts = ssl_test_lib:ssl_options(client_rsa_opts, Config),
ServerOpts = ssl_test_lib:ssl_options(server_rsa_opts, Config),