From 0ed2573cbd55c92e9125c9dc70fa1ca7fed82872 Mon Sep 17 00:00:00 2001 From: Jakub Witczak Date: Thu, 6 Feb 2025 19:00:44 +0100 Subject: [PATCH] ssh: sftp reject packets exceeding limit --- lib/ssh/src/ssh_sftpd.erl | 47 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index c86ed2cb8199..6bcad0d056e7 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -27,7 +27,7 @@ -behaviour(ssh_server_channel). -include_lib("kernel/include/file.hrl"). - +-include_lib("kernel/include/logger.hrl"). -include("ssh.hrl"). -include("ssh_xfer.hrl"). -include("ssh_connect.hrl"). %% For ?DEFAULT_PACKET_SIZE and ?DEFAULT_WINDOW_SIZE @@ -128,9 +128,8 @@ init(Options) -> %% Description: Handles channel messages %%-------------------------------------------------------------------- handle_ssh_msg({ssh_cm, _ConnectionManager, - {data, _ChannelId, Type, Data}}, State) -> - State1 = handle_data(Type, Data, State), - {ok, State1}; + {data, ChannelId, Type, Data}}, State) -> + handle_data(Type, ChannelId, Data, State); handle_ssh_msg({ssh_cm, _, {eof, ChannelId}}, State) -> {stop, ChannelId, State}; @@ -187,24 +186,42 @@ terminate(_, #state{handles=Handles, file_handler=FileMod, file_state=FS}) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- -handle_data(0, <>, +handle_data(0, ChannelId, <>, State = #state{pending = <<>>}) -> <> = Msg, NewState = handle_op(Op, ReqId, Data, State), case Rest of <<>> -> - NewState; + {ok, NewState}; _ -> - handle_data(0, Rest, NewState) + handle_data(0, ChannelId, Rest, NewState) end; - -handle_data(0, Data, State = #state{pending = <<>>}) -> - State#state{pending = Data}; - -handle_data(Type, Data, State = #state{pending = Pending}) -> - handle_data(Type, <>, - State#state{pending = <<>>}). - +handle_data(0, _ChannelId, Data, State = #state{pending = <<>>}) -> + {ok, State#state{pending = Data}}; +handle_data(Type, ChannelId, Data0, State = #state{pending = Pending}) -> + Data = <>, + Size = byte_size(Data), + case Size > ?SSH_MAX_PACKET_SIZE of + true -> + ReportFun = + fun([S]) -> + Report = + #{label => {error_logger, error_report}, + report => + io_lib:format("SFTP packet size (~B) exceeds the limit!", + [S])}, + Meta = + #{error_logger => + #{tag => error_report,type => std_error}, + report_cb => fun(#{report := Msg}) -> {Msg, []} end}, + {Report, Meta} + end, + ?LOG_ERROR(ReportFun, [Size]), + {stop, ChannelId, State}; + _ -> + handle_data(Type, ChannelId, Data, State#state{pending = <<>>}) + end. + handle_op(?SSH_FXP_INIT, Version, B, State) when is_binary(B) -> XF = State#state.xf, Vsn = lists:min([XF#ssh_xfer.vsn, Version]),