diff options
author | Ingela Anderton Andin <ingela@erlang.org> | 2020-05-28 11:01:00 +0200 |
---|---|---|
committer | Ingela Anderton Andin <ingela@erlang.org> | 2020-06-11 10:18:21 +0200 |
commit | 5a9a2fe727ba43bd6352552d42db85255b4fd4ff (patch) | |
tree | 94a7ea39e095c92f1542cca177a0be67da6c69c9 | |
parent | 6d5a5f31c36bbdaad21585d25974177bd1b75e66 (diff) | |
download | erlang-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.erl | 8 | ||||
-rw-r--r-- | lib/ssl/test/ssl_api_SUITE.erl | 34 |
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), |