Skip to content

Commit eaf9550

Browse files
committed
Fix extended data infinite loop in sftpd
1 parent 1b4737f commit eaf9550

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

lib/ssh/src/ssh_sftpd.erl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ handle_data(0, ChannelId, <<?UINT32(Len), Msg:Len/binary, Rest/binary>>,
235235
end;
236236
handle_data(0, _ChannelId, Data, State = #state{pending = <<>>}) ->
237237
{ok, State#state{pending = Data}};
238-
handle_data(Type, ChannelId, Data0, State = #state{pending = Pending}) ->
238+
handle_data(0, ChannelId, Data0, State = #state{pending = Pending}) ->
239239
Data = <<Pending/binary, Data0/binary>>,
240240
Size = byte_size(Data),
241241
case Size > ?SSH_MAX_PACKET_SIZE of
@@ -256,8 +256,11 @@ handle_data(Type, ChannelId, Data0, State = #state{pending = Pending}) ->
256256
?LOG_ERROR(ReportFun, [Size]),
257257
{stop, ChannelId, State};
258258
_ ->
259-
handle_data(Type, ChannelId, Data, State#state{pending = <<>>})
260-
end.
259+
handle_data(0, ChannelId, Data, State#state{pending = <<>>})
260+
end;
261+
handle_data(_Type, _ChannelId, _Data, State) ->
262+
%% Same as openssh sftpd, we ignore extended data
263+
{ok, State}.
261264

262265
handle_op(?SSH_FXP_INIT, Version, B, State) when is_binary(B) ->
263266
XF = State#state.xf,

lib/ssh/test/ssh_sftpd_SUITE.erl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
ver3_open_flags/1,
5656
ver3_rename/1,
5757
ver6_basic/1,
58-
write_file/1
58+
write_file/1,
59+
extended_data_no_infinite_loop/1
5960
]).
6061

6162
-include_lib("common_test/include/ct.hrl").
@@ -104,7 +105,8 @@ all() ->
104105
root_with_cwd,
105106
relative_path,
106107
open_file_dir_v5,
107-
open_file_dir_v6].
108+
open_file_dir_v6,
109+
extended_data_no_infinite_loop].
108110

109111
groups() ->
110112
[].
@@ -792,6 +794,17 @@ open_file_dir_v6(Config) when is_list(Config) ->
792794
?ACE4_READ_DATA bor ?ACE4_READ_ATTRIBUTES,
793795
?SSH_FXF_OPEN_EXISTING).
794796

797+
%%--------------------------------------------------------------------
798+
extended_data_no_infinite_loop(Config) when is_list(Config) ->
799+
%% Regression test for CVE-2026-54886, sending extended data to ssh_sftpd.erl
800+
%% caused an infinite loop
801+
{Cm, Channel} = proplists:get_value(sftp, Config),
802+
ok = ssh_connection:send(Cm, Channel, 1, <<"trigger">>),
803+
804+
Data = <<?UINT32(5), ?SSH_FXP_INIT, ?UINT32(6)>>,
805+
ok = ssh_connection:send(Cm, Channel, Data),
806+
{ok, <<?SSH_FXP_VERSION, ?UINT32(_Version), _/binary>>, _} = reply(Cm, Channel).
807+
795808
%%--------------------------------------------------------------------
796809
%% Internal functions ------------------------------------------------
797810
%%--------------------------------------------------------------------
@@ -806,7 +819,9 @@ prep(Config) ->
806819
%% Initial config
807820
DataDir = proplists:get_value(data_dir, Config),
808821
FileName = filename:join(DataDir, "test.txt"),
809-
file:copy(FileName, TestFile),
822+
{ok, Data0} = file:read_file(FileName),
823+
Data = ssh_test_lib:remove_comment(Data0),
824+
ok = file:write_file(TestFile, string:chomp(Data)),
810825
Mode = 8#00400 bor 8#00200 bor 8#00040, % read & write owner, read group
811826
{ok, FileInfo} = file:read_file_info(TestFile),
812827
ok = file:write_file_info(TestFile,

0 commit comments

Comments
 (0)