Subject: Unchecked error in _libssh2_channel_write causes infinite loop

Unchecked error in _libssh2_channel_write causes infinite loop

From: Matthew Booth <>
Date: Mon, 12 Mar 2012 11:40:15 +0000

I've been encountering an issue in my application where it reliably gets
into an infinite loop part way through a very large data transfer. The
application is exclusively sending data during the transfer. The problem
seems to relate to a transport error which I haven't yet gotten to the
bottom of. However, the infinite loop seems to be down to an unchecked
error in _libssh2_channel_write():

         /* drain the incoming flow first, mostly to make sure we get all
          * pending window adjust packets */
             rc = _libssh2_transport_read(session);
         while (rc > 0);

         if(channel->local.window_size <= 0)
             /* there's no room for data so we stop */
             return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);

In my case, _libssh2_transport_read is returning
LIBSSH2_ERROR_SOCKET_RECV (don't know why yet). The result of this in
the above code is that _libssh2_channel_write returns 0, throwing away
the error information. My code spots a zero return, checks for eof,
doesn't find one and goes round again: infinite loop.

I would just submit a patch which adds "if (rc<0) return rc;"
immediately after the read loop, but it seems like the author has
intentionally not done this here. Git commit
3c71ad4fce745876f7e7ad33b846518f2d50edf6 and its associated mailing list
thread doesn't shed any light on why only EAGAIN is handled. Can anybody



Matthew Booth, RHCA, RHCSS
Red Hat Engineering, Virtualisation Team
GPG ID:  D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
Received on 2012-03-12