[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix ssh_event_add_session() when session socket has two pollhandlers


Hello,


Here's a patch to fix an issue when moving pollhandlers from a session to a ssh_event object.

The issue occurs when session socket has two different pollhandler (for poll_in and poll_out, when using proxycommand in my case),

only the poll_in was moved and poll_out was still in session poll context due to a side effect in ssh_poll_ctx_remove().


This patch fix the loop in ssh_event_add_session().


Regards,


Meng
From 0d584e2453d0f9f296545e5b303413afb4bcb2f1 Mon Sep 17 00:00:00 2001
From: Meng Tan <mtan@xxxxxxxxxx>
Date: Thu, 29 Mar 2018 11:34:54 +0200
Subject: [PATCH] Fix ssh_event_add_session() when session socket has two
 pollhandlers

Signed-off-by: Meng Tan <mtan@xxxxxxxxxx>
---
 src/poll.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/poll.c b/src/poll.c
index c698c13f..134b5e3d 100644
--- a/src/poll.c
+++ b/src/poll.c
@@ -812,7 +812,6 @@ void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p)
  *          SSH_ERROR   on failure
  */
 int ssh_event_add_session(ssh_event event, ssh_session session) {
-    unsigned int i;
     ssh_poll_handle p;
 #ifdef WITH_SERVER
     struct ssh_iterator *iterator;
@@ -824,8 +823,11 @@ int ssh_event_add_session(ssh_event event, ssh_session session) {
     if(session->default_poll_ctx == NULL) {
         return SSH_ERROR;
     }
-    for(i = 0; i < session->default_poll_ctx->polls_used; i++) {
-        p = session->default_poll_ctx->pollptrs[i];
+    while (session->default_poll_ctx->polls_used > 0) {
+        p = session->default_poll_ctx->pollptrs[0];
+        /* ssh_poll_ctx_remove() decrements
+         * session->default_poll_ctx->polls_used
+         */
         ssh_poll_ctx_remove(session->default_poll_ctx, p);
         ssh_poll_ctx_add(event->ctx, p);
         /* associate the pollhandler with a session so we can put it back
@@ -961,11 +963,19 @@ int ssh_event_remove_session(ssh_event event, ssh_session session) {
     for(i = 0; i < used; i++) {
     	p = event->ctx->pollptrs[i];
     	if(p->session == session){
+            /* ssh_poll_ctx_remove() decrements
+             * event->ctx->polls_used
+             */
             ssh_poll_ctx_remove(event->ctx, p);
             p->session = NULL;
             ssh_poll_ctx_add(session->default_poll_ctx, p);
             rc = SSH_OK;
-            used = 0;
+            /* restart the loop
+             * a session can initially have two pollhandlers
+             */
+            used = event->ctx->polls_used;
+            i = 0;
+
         }
     }
 #ifdef WITH_SERVER
-- 
2.11.0


Archive administrator: postmaster@lists.cynapses.org