[erlang-bugs] ssh bug: bad window_adjust response

Daniel Goertzen <>
Tue Aug 28 16:08:03 CEST 2012


Thanks.  This diff seems to work for me:

$ diff -Nbaur ssh_connection.erl.bak ssh_connection.erl
--- ssh_connection.erl.bak      2012-08-28 08:20:36.340557700 -0500
+++ ssh_connection.erl  2012-08-28 08:21:50.425465200 -0500
@@ -445,7 +445,7 @@

     Replies = lists:map(fun({Type, Data}) ->
                                {connection_reply, ConnectionPid,
-                                channel_data_msg(ChannelId, Type, Data)}
+
 channel_data_msg(Channel#channel.remote_id, Type, Data)}
                        end, SendList),
     FlowCtrlMsgs = flow_control(Channel, Cache),
     {{replies, Replies ++ FlowCtrlMsgs}, Connection};

Dan.


On Tue, Aug 28, 2012 at 1:57 AM, Ingela Anderton Andin <
> wrote:

> Hello!
>
> Yes that is a bug, thanks for catching it. I will fix it.
>
> Regards Ingela Erlang OTP/team - Ericsson AB
>
> Daniel Goertzen wrote:
>
>> Okay, I've found the real bug now. :)
>>
>> When Erlang ssh receives a "ssh_msg_channel_window_**adjust" message and
>> there is outstanding data to transmit, the code will generate
>> "ssh_msg_channel_data" messages with the wrong channel number.  The remote
>> system observes a protocol error and drops the connection.
>>
>> The problem is in ssh_connection.erl approximately line 450:
>>
>> handle_msg(#ssh_msg_channel_**window_adjust{recipient_**channel =
>> *ChannelId*,
>>
>>  bytes_to_add = Add},   #connection{channel_cache = Cache} = Connection,
>>   ConnectionPid, _) ->
>>         #channel{send_window_size = Size} = Channel0 =
>> ssh_channel:cache_lookup(**Cache, ChannelId),
>>     {SendList, Channel} =  %% TODO: Datatype 0 ?
>> update_send_window(Channel0#**channel{send_window_size = Size + Add},
>>   0, <<>>, Connection),
>>         Replies = lists:map(fun({Type, Data}) -> {connection_reply,
>> ConnectionPid,
>> channel_data_msg(*ChannelId*, Type, Data)}  % <-- *bzzt, wrong*
>>
>> end, SendList),
>>     FlowCtrlMsgs = flow_control(Channel, Cache),
>>     {{replies, Replies ++ FlowCtrlMsgs}, Connection};
>>
>>
>> Below is a trace of a channel where I did a ssh_connection:send() of a
>> 13MB binary.  The first window worth of data is correctly sent to channel
>> 2, but the second window of data is incorrectly sent to channel 7.  The
>> remote SSH is OpenSSH.  See bolded sections below
>>
>> firmware size 13417472
>> c{<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{**ssh_msg_channel_open,"session"**,7,65536,32768,<<0
>> bytes>>}}]}
>> al{<0.134.0>,"->",ssh_**connection,handle_msg,[{ssh_**
>> msg_channel_open_confirmation,**7,2,0,32768,<<0
>> bytes>>},{connection,[{7,{<0.**145.0>,#Ref<0.0.0.630>}}],**
>> 65583,[],8,undefined,**undefined,undefined,undefined,**
>> undefined,undefined,<0.133.0>}**,<0.135.0>,client]}
>> ling exec now...
>> opening channel
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_requst_reply,{<0.145.**0>,#Ref<0.0.0.630>},{open,7}}]**}
>> calling ssh exec
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{**ssh_msg_channel_request,2,"**exec",true,[<<16
>> bytes>>]}}]}
>> {<0.134.0>,"->",ssh_**connection,handle_msg,[{ssh_**
>> msg_channel_window_adjust,7,**87380},{connection,[{7,{<0.**
>> 145.0>,#Ref<0.0.0.634>}}],**65583,[],8,undefined,**
>> undefined,undefined,undefined,**undefined,undefined,<0.133.0>}**
>> ,<0.135.0>,client]}
>> {<0.134.0>,"->",ssh_**connection,handle_msg,[{ssh_**
>> msg_channel_success,7},{**connection,[{7,{<0.145.0>,#**
>> Ref<0.0.0.634>}}],65583,[],8,**undefined,undefined,undefined,**
>> undefined,undefined,undefined,**<0.133.0>},<0.135.0>,client]}
>> ca{<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_requst_reply,{<0.145.**0>,#Ref<0.0.0.634>},success}]}
>> lled send_stdin
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,2*,<<**32768
>> bytes>>}}]}
>> in{<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,2*,<<**32768
>> bytes>>}}]}
>>  {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,2*,<<**21844
>> bytes>>}}]}
>>
>> i{<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> flow_control,65583,{channel,"**session","exec",<0.145.0>,{<0.**
>> 145.0>,#Ref<0.0.0.639>},7,**65536,32768,false,2,0,32768,**false,[{0,<<13330092
>> bytes>>}]},{<0.145.0>,#Ref<0.**0.0.639>},ok}]}
>> o loop
>> {<0.134.0>,"->",ssh_**connection,handle_msg,[{*ssh_**
>> msg_channel_window_adjust*,*7***,124222},{connection,[],65583,**
>> [],8,undefined,undefined,**undefined,undefined,undefined,**
>> undefined,<0.133.0>},<0.135.0>**,client]}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,7*,<<**32768
>> bytes>>}}]}
>> io{<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,7*,<<**32768
>> bytes>>}}]}
>>
>>  loop got{data,7,1,<<"calling_user 101\nfile_user 0\n">>}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,7*,<<**32768
>> bytes>>}}]}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{***ssh_msg_channel_data,7*,<<**25918
>> bytes>>}}]}
>>
>> i{<0.134.0>,"->",ssh_**connection,handle_msg,[{ssh_**
>> msg_channel_extended_data,7,1,**<<29 bytes>>},{connection,[],65583,**
>> [],8,undefined,undefined,**undefined,undefined,undefined,**
>> undefined,<0.133.0>},<0.135.0>**,client]}
>> n {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_data,<0.145.0>,{data,**7,1,<<29 bytes>>}}]}
>> io loop
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{**ssh_msg_channel_window_adjust,**2,29}}]}
>> {<0.134.0>,"->",ssh_**connection,handle_msg,[{ssh_**
>> msg_channel_extended_data,7,1,**<<25 bytes>>},{connection,[],65583,**
>> [],8,undefined,undefined,**undefined,undefined,undefined,**
>> undefined,<0.133.0>},<0.135.0>**,client]}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_data,<0.145.0>,{data,**7,1,<<25 bytes>>}}]}
>> io loop got{data,7,1,<<"proceeding with transfer\n">>}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> connection_reply,<0.135.0>,{**ssh_msg_channel_window_adjust,**2,25}}]}
>> in io loop
>> {<0.134.0>,"->",ssh_**connection,handle_msg,[*{ssh_**msg_disconnect,2,"Received
>> data for nonexistent channel 7*.",[]},{connection,[],65583,**
>> [],8,undefined,undefined,**undefined,undefined,undefined,**
>> undefined,<0.133.0>},<0.135.0>**,client]}
>>
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_data,<0.145.0>,{**closed,7}}]}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_data,<0.132.0>,{**closed,6}}]}
>> {<0.134.0>,"->",ssh_**connection_manager,send_msg,[{**
>> channel_data,<0.132.0>,{**closed,5}}]}
>>
>>
>> Dan.
>>
>> ------------------------------**------------------------------**
>> ------------
>>
>> ______________________________**_________________
>> erlang-bugs mailing list
>> 
>> http://erlang.org/mailman/**listinfo/erlang-bugs<http://erlang.org/mailman/listinfo/erlang-bugs>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20120828/62d70316/attachment.html>


More information about the erlang-bugs mailing list