File 5861-ftp-Solve-race-condition-between-control-and-data-ch.patch of Package erlang
From d96333d3351511a95c3103001e06f97684059d69 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Tue, 4 Jun 2024 09:36:36 +0200
Subject: [PATCH] ftp: Solve race condition between control and data channel
Closes #8454
---
lib/ftp/src/ftp_internal.erl | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/lib/ftp/src/ftp_internal.erl b/lib/ftp/src/ftp_internal.erl
index 2b8ee8f9e1..fc77676cb9 100644
--- a/lib/ftp/src/ftp_internal.erl
+++ b/lib/ftp/src/ftp_internal.erl
@@ -1134,9 +1134,9 @@ handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, caller = recv_bin,
data = Data} = State0)
when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
?DBG("Data channel close",[]),
- State = activate_ctrl_connection(State0),
- {noreply, State#state{dsock = undefined, data = <<>>,
- caller = {recv_bin, Data}}};
+ State = activate_ctrl_connection(State0#state{dsock = undefined, data = <<>>,
+ caller = {recv_bin, Data}}),
+ {noreply, State};
handle_info({Cls, Socket}, #state{dsock = {Trpt,Socket}, data = Data,
caller = {handle_dir_result, Dir}}
@@ -1200,7 +1200,11 @@ handle_info({Transport, Socket, Data}, #state{csock = {Transport, Socket},
handle_info({Cls, Socket}, #state{csock = {Trpt, Socket}})
when {Cls,Trpt}=={tcp_closed,tcp} ; {Cls,Trpt}=={ssl_closed,ssl} ->
exit(normal); %% User will get error message from terminate/2
-
+%% Perhaps handle data left on the control channel
+handle_info({Cls, _NotCSock}, #state{dsock = undefined} = State0)
+ when Cls == tcp_closed; Cls == ssl_closed ->
+ State = activate_ctrl_connection(State0),
+ {noreply, State};
handle_info({Err, Socket, Reason}, _) when Err==tcp_error ; Err==ssl_error ->
Report =
io_lib:format("~p on socket: ~p for reason: ~p~n",
@@ -1209,7 +1213,6 @@ handle_info({Err, Socket, Reason}, _) when Err==tcp_error ; Err==ssl_error ->
%% If tcp does not work the only option is to terminate,
%% this is the expected behavior under these circumstances.
exit(normal); %% User will get error message from terminate/2
-
%% Monitor messages - if the process owning the ftp connection goes
%% down there is no point in continuing.
handle_info({'DOWN', _Ref, _Type, _Process, normal}, State) ->
@@ -1651,6 +1654,10 @@ handle_ctrl_result({pos_compl, _}, #state{caller = {recv_bin, Data},
close_data_connection(State),
{noreply, State#state{client = undefined, caller = undefined}};
+handle_ctrl_result({pos_compl, _}, #state{caller = recv_bin} = State0) ->
+ State = activate_data_connection(State0),
+ {noreply, State};
+
handle_ctrl_result({Status, _}, #state{caller = recv_bin} = State) ->
close_data_connection(State),
ctrl_result_response(Status, State#state{dsock = undefined},
--
2.43.0