Skip to content

Commit 70a5a1c

Browse files
committed
Merge branch 'maint'
2 parents ee63558 + e2a7728 commit 70a5a1c

2 files changed

Lines changed: 21 additions & 5 deletions

File tree

lib/ssh/src/ssh_sftpd.erl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ handle_data(0, ChannelId, <<?UINT32(Len), Msg:Len/binary, Rest/binary>>,
264264
end;
265265
handle_data(0, _ChannelId, Data, State = #state{pending = <<>>}) ->
266266
{ok, State#state{pending = Data}};
267-
handle_data(Type, ChannelId, Data0, State = #state{pending = Pending}) ->
267+
handle_data(0, ChannelId, Data0, State = #state{pending = Pending}) ->
268268
Data = <<Pending/binary, Data0/binary>>,
269269
Size = byte_size(Data),
270270
case Size > ?SSH_MAX_PACKET_SIZE of
@@ -285,8 +285,11 @@ handle_data(Type, ChannelId, Data0, State = #state{pending = Pending}) ->
285285
?LOG_ERROR(ReportFun, [Size]),
286286
{stop, ChannelId, State};
287287
_ ->
288-
handle_data(Type, ChannelId, Data, State#state{pending = <<>>})
289-
end.
288+
handle_data(0, ChannelId, Data, State#state{pending = <<>>})
289+
end;
290+
handle_data(_Type, _ChannelId, _Data, State) ->
291+
%% Same as openssh sftpd, we ignore extended data
292+
{ok, State}.
290293

291294
%% From draft-ietf-secsh-filexfer-02 "The file handle strings MUST NOT be longer than 256 bytes."
292295
handle_op(Request, ReqId, <<?UINT32(HLen), _/binary>>, State = #state{xf = XF})

lib/ssh/test/ssh_sftpd_SUITE.erl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@
6363
ver3_rename/1,
6464
ver6_basic/1,
6565
write_file/1,
66-
access_attributes_outside_root/1
66+
access_attributes_outside_root/1,
67+
extended_data_no_infinite_loop/1
6768
]).
6869

6970
-include_lib("common_test/include/ct.hrl").
@@ -127,7 +128,8 @@ all() ->
127128
relative_path,
128129
open_file_dir_v5,
129130
open_file_dir_v6,
130-
access_attributes_outside_root].
131+
access_attributes_outside_root,
132+
extended_data_no_infinite_loop].
131133

132134
groups() ->
133135
[].
@@ -1025,6 +1027,17 @@ access_attributes_outside_root(Config) when is_list(Config) ->
10251027
file:delete(OutsideRootFile)
10261028
end.
10271029

1030+
%%--------------------------------------------------------------------
1031+
extended_data_no_infinite_loop(Config) when is_list(Config) ->
1032+
%% Regression test for CVE-2026-54886, sending extended data to ssh_sftpd.erl
1033+
%% caused an infinite loop
1034+
{Cm, Channel} = proplists:get_value(sftp, Config),
1035+
ok = ssh_connection:send(Cm, Channel, 1, <<"trigger">>),
1036+
1037+
Data = <<?UINT32(5), ?SSH_FXP_INIT, ?UINT32(6)>>,
1038+
ok = ssh_connection:send(Cm, Channel, Data),
1039+
{ok, <<?SSH_FXP_VERSION, ?UINT32(_Version), _/binary>>, _} = reply(Cm, Channel).
1040+
10281041
%%--------------------------------------------------------------------
10291042
%% Internal functions ------------------------------------------------
10301043
%%--------------------------------------------------------------------

0 commit comments

Comments
 (0)