From 64ce7cb90966cb66a65b160df852dd8032b56cce Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Fri, 20 Apr 2018 08:18:18 +0000
Subject: [PATCH] Fix race-condition causing SSH errors: Terminal Server SSH
 ERROR 'Bad argument, parameter 1' (-1)  ... from output_thread

The bbs_thread() sets the global/server sbbs ssh_mode to false and ssh_session
to 0 (the "parameter 1" value used in the cryptlib function calls in
output_thread) but was doing this without owning the ssh_mutex, so the
output_thread had a race condition where it would check ssh_mode=true and
then use grab the ssh_mutex and use ssh_session in a few cryptlib function
calls. The fix for the bbs_thread() to grab the ssh_mutex before setting
ssh_mode to false and ssh_session to 0 and have the output_thread() re-check
the ssh_mode after grabbing the ssh_mutex and not call any cryptlib
functions if ssh_mode was set to false while waiting for the mutex.

The cause would have been more obvious if the various cryptlib error/log
messages contained the cryptlib session ID value (which was 0 in this case).
---
 src/sbbs3/main.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 5afd112dcc..f60900ff37 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -2439,6 +2439,10 @@ void output_thread(void* arg)
 				pthread_mutex_unlock(&sbbs->ssh_mutex);
 				break;
 			}
+			if(!sbbs->ssh_mode) {
+				pthread_mutex_unlock(&sbbs->ssh_mutex);
+				continue;
+			}
 			if (cryptStatusError((err=cryptSetAttribute(sbbs->ssh_session, CRYPT_SESSINFO_SSH_CHANNEL, sbbs->session_channel)))) {
 				GCESSTR(err, node, sbbs->ssh_session, "setting channel");
 				ssh_errors++;
@@ -5790,8 +5794,10 @@ NO_PASSTHRU:
 			/* Wait for pending data to be sent then turn off ssh_mode for uber-output */
 			while(sbbs->output_thread_running && RingBufFull(&sbbs->outbuf))
 				SLEEP(1);
+			pthread_mutex_lock(&sbbs->ssh_mutex);
 			sbbs->ssh_mode=false;
 			sbbs->ssh_session=0; // Don't allow subsequent SSH connections to affect this one (!)
+			pthread_mutex_unlock(&sbbs->ssh_mutex);
 		}
 #endif
 
-- 
GitLab