Ticket #8 (closed defect)

Opened 12 years ago

Last modified 10 years ago

infinite loop on socket shutdown

Reported by: hillerj Owned by:
Priority: normal Milestone:
Component: Version:
Keywords: Cc: hillerj, sshattered, mwbourgeois, bagder
Blocked By: Blocks:


The problem I am having shows up when I hit the
MaxStartups? configuration limit in sshd. The program I
wrote spins up multiple threads that each connect to a
unix box using libssh2, executes a couple commands and
then exit. Let's say the MaxStartups? parameter for
sshd is 4 and I spin up 5 threads. Since the fifth
thread hits the MaxStartups? limit, sshd closes the
socket, which then causes that thread to go into an
infinite loop in the function libssh2_banner_receive.
The infinite loop is due to the socket function recv
returning 0. Line 111 of session.c is the culprit.
Now, I am running on Windows but I checked the
documentation for recv on Windows and Unix and they
both state that when recv returns 0 it means the peer
has shutdown the socket. It seems like line 111 in
session.c should be changed to something like "if(ret

0) return 1;". I also looked at other places that

the function recv is used and it looks like the
function libssh2_blocking_read could have the same
infinite loop problem due to line 688 of packet.c. I
am not sure if my research is correct so please let me
know. Thanks.

Change History

comment:1 Changed 11 years ago by sshattered

I have seen a similar problem in packet.c where the packet
'count' to be achieved is 782254606 and the received bytes
are always zero. The socket I use in this case is
non-blocking as passed in to libssh2. The read produces a
zero return each time in the loop and continues forever with
a cooresponding cpu spike.

The packet capture shows a steady stream of resets by the
remote host, "administratively prohibited" with a code 10.

To continue locally for debugging purposes, inserting:
"if (ret > 0) continue;if (ret == 0) break;"
at line 688 in fn libssh2_blocking_read() will allow a reset
socket to exit with an error of -5 from the statrup function
and return control of the client to you.

comment:2 Changed 11 years ago by sshattered

Actually, if you want it to function normally again:

"if (ret > 0){bytes_read+=ret;continue;}if (ret == 0) break;"

at the beginning of line 688 will allow normal usage.

comment:3 Changed 11 years ago by mwbourgeois

I've had this problem with both of the mentioned instances of the recv causing an infinite loop when the remote host closes the connection. I wrote a patch against the current CVS which should fix this problem which I will attempt to attach to this report and submit for inclusion in CVS.

comment:4 Changed 11 years ago by mwbourgeois

diff -Naur libssh2/src/packet.c libssh2-uwhousing20061221/src/packet.c
--- libssh2/src/packet.c 2006-12-21 08:29:50.349858448 -0600
+++ libssh2-uwhousing20061221/src/packet.c 2006-12-21 09:47:27.499864032 -0600
@@ -702,7 +702,7 @@

return -1;


  • if (ret == 0) continue;

+ if (ret == 0) break;

bytes_read += ret;


diff -Naur libssh2/src/session.c libssh2-uwhousing20061221/src/session.c
--- libssh2/src/session.c 2006-12-21 08:29:50.524831848 -0600
+++ libssh2-uwhousing20061221/src/session.c 2006-12-21 08:32:12.775206504 -0600
@@ -125,9 +125,10 @@

/* Some kinda error, but don't break for non-blocking issues */
return 1;


+ continue;


  • if (ret <= 0) continue;

+ if (ret == 0) return 1;

if (c == '\0') {

/* NULLs are not allowed in SSH banners */

comment:5 Changed 10 years ago by bagder

This is addressed in current CVS, if still present please open a new bug report

Note: See TracTickets for help on using tickets.