From 8efc1ab04cbc529d28568b038d54139d238087f1 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Tue, 7 Aug 2018 15:06:42 +0200
Subject: ssl: Correct close handling

Transport accepted sockets that are in the error state, was not closed
properly.
---
 lib/ssl/src/ssl_connection.erl   |  2 ++
 lib/ssl/test/ssl_basic_SUITE.erl | 30 +++++++++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 064350e6de..4b3a6cde01 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -634,6 +634,8 @@ init(_Type, _Event, _State, _Connection) ->
             tls_connection | dtls_connection) ->
 		   gen_statem:state_function_result().
 %%--------------------------------------------------------------------
+error({call, From}, {close, _}, State, _Connection) ->
+    stop_and_reply(normal, {reply, From, ok}, State);
 error({call, From}, _Msg, State, _Connection) ->
     {next_state, ?FUNCTION_NAME, State, [{reply, From, {error, closed}}]}.
 
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 0381d0d87d..013786d863 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -243,7 +243,8 @@ error_handling_tests()->
      recv_active,
      recv_active_once,
      recv_error_handling,
-     call_in_error_state
+     call_in_error_state,
+     close_in_error_state
     ].
 
 error_handling_tests_tls()->
@@ -4036,6 +4037,33 @@ run_error_server([ Pid | Opts]) ->
 
 %%--------------------------------------------------------------------
 
+close_in_error_state() ->
+    [{doc,"Special case of closing socket in error state"}].
+close_in_error_state(Config) when is_list(Config) ->
+    ServerOpts0 = ssl_test_lib:ssl_options(server_opts, Config),
+    ServerOpts = [{cacertfile, "foo.pem"} | proplists:delete(cacertfile, ServerOpts0)],
+    ClientOpts = ssl_test_lib:ssl_options(client_opts, Config),
+    _ = spawn_link(?MODULE, run_error_server_close, [[self() | ServerOpts]]),
+    receive
+        {_Pid, Port} ->
+            spawn_link(?MODULE, run_client_error, [[Port, ClientOpts]])
+    end,
+    receive
+        ok ->
+            ok;
+        Other ->
+            ct:fail(Other)
+    end.
+
+run_error_server_close([Pid | Opts]) ->
+    {ok, Listen} = ssl:listen(0, Opts),
+    {ok,{_, Port}} = ssl:sockname(Listen),
+    Pid ! {self(), Port},
+    {ok, Socket} = ssl:transport_accept(Listen),
+    Pid ! ssl:close(Socket).
+
+%%--------------------------------------------------------------------
+
 rizzo() ->
     [{doc, "Test that there is a 1/n-1-split for non RC4 in 'TLS < 1.1' as it is
     vunrable to Rizzo/Dungon attack"}].
-- 
cgit v1.2.3