See the patch attached for the details.

Cheers!
>From 3a54debffddbab12749aefeacbfeaa98e44cb4f1 Mon Sep 17 00:00:00 2001
From: Salvador Fandino <[email protected]>
Date: Wed, 26 Aug 2015 14:21:44 +0200
Subject: [PATCH] Detect bad usage of libssh2_channel_process_startup

A common novice programmer error (at least among those using
the wrapping Perl module Net::SSH2), is to try to reuse
channels.

This patchs detects that incorrect usage and fails with a
LIBSSH2_ERROR_BAD_USE error instead of hanging.

Signed-off-by: Salvador Fandino <[email protected]>
---
 src/channel.c      | 11 ++++++++---
 src/libssh2_priv.h |  3 ++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/channel.c b/src/channel.c
index cb0d818..32d914d 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1252,6 +1252,11 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
         { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
     int rc;
 
+    if (channel->process_state == libssh2_NB_state_end) {
+        return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
+                              "Channel can not be reused");
+    }
+
     if (channel->process_state == libssh2_NB_state_idle) {
         /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
         channel->process_packet_len = request_len + 10;
@@ -1298,7 +1303,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
         else if (rc) {
             LIBSSH2_FREE(session, channel->process_packet);
             channel->process_packet = NULL;
-            channel->process_state = libssh2_NB_state_idle;
+            channel->process_state = libssh2_NB_state_end;
             return _libssh2_error(session, rc,
                                   "Unable to send channel request");
         }
@@ -1320,14 +1325,14 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
         if (rc == LIBSSH2_ERROR_EAGAIN) {
             return rc;
         } else if (rc) {
-            channel->process_state = libssh2_NB_state_idle;
+            channel->process_state = libssh2_NB_state_end;
             return _libssh2_error(session, rc,
                                   "Failed waiting for channel success");
         }
 
         code = data[0];
         LIBSSH2_FREE(session, data);
-        channel->process_state = libssh2_NB_state_idle;
+        channel->process_state = libssh2_NB_state_end;
 
         if (code == SSH_MSG_CHANNEL_SUCCESS)
             return 0;
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index efc917c..9130201 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -215,7 +215,8 @@ typedef enum
     libssh2_NB_state_jump2,
     libssh2_NB_state_jump3,
     libssh2_NB_state_jump4,
-    libssh2_NB_state_jump5
+    libssh2_NB_state_jump5,
+    libssh2_NB_state_end
 } libssh2_nonblocking_states;
 
 typedef struct packet_require_state_t
-- 
2.1.4

_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to