]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
libssh2: ignore timeout during disconnect
authorDaniel Stenberg <daniel@haxx.se>
Mon, 3 May 2021 11:21:15 +0000 (13:21 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 4 May 2021 06:20:40 +0000 (08:20 +0200)
... to avoid memory leaks!

libssh2 is tricky as we have to deal with the non-blockiness even in
close and shutdown cases. In the cases when we shutdown after a timeout
already expired, it is crucial that curl doen't let the timeout abort
the shutdown process as that then leaks memory!

Reported-by: Benjamin Riefenstahl
Fixes #6990

lib/vssh/libssh2.c

index d2bf8661da3a895bd1626b65c609ec4ff92158cb..c39870387d51af2057d9e331ce5471d71fbbb1aa 100644 (file)
@@ -2931,7 +2931,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
 
 static CURLcode ssh_block_statemach(struct Curl_easy *data,
                                     struct connectdata *conn,
-                                    bool duringconnect)
+                                    bool disconnect)
 {
   struct ssh_conn *sshc = &conn->proto.sshc;
   CURLcode result = CURLE_OK;
@@ -2945,17 +2945,19 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data,
     if(result)
       break;
 
-    if(Curl_pgrsUpdate(data))
-      return CURLE_ABORTED_BY_CALLBACK;
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(data))
+        return CURLE_ABORTED_BY_CALLBACK;
 
-    result = Curl_speedcheck(data, now);
-    if(result)
-      break;
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
 
-    left = Curl_timeleft(data, NULL, duringconnect);
-    if(left < 0) {
-      failf(data, "Operation timed out");
-      return CURLE_OPERATION_TIMEDOUT;
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
     }
 
     if(block) {
@@ -3278,10 +3280,8 @@ static CURLcode scp_disconnect(struct Curl_easy *data,
 
   if(sshc->ssh_session) {
     /* only if there's a session still around to use! */
-
     state(data, SSH_SESSION_DISCONNECT);
-
-    result = ssh_block_statemach(data, conn, FALSE);
+    result = ssh_block_statemach(data, conn, TRUE);
   }
 
   return result;
@@ -3295,10 +3295,9 @@ static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
   struct SSHPROTO *sshp = data->req.p.ssh;
   struct connectdata *conn = data->conn;
 
-  if(!status) {
+  if(!status)
     /* run the state-machine */
     result = ssh_block_statemach(data, conn, FALSE);
-  }
   else
     result = status;
 
@@ -3438,7 +3437,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data,
   if(sshc->ssh_session) {
     /* only if there's a session still around to use! */
     state(data, SSH_SFTP_SHUTDOWN);
-    result = ssh_block_statemach(data, conn, FALSE);
+    result = ssh_block_statemach(data, conn, TRUE);
   }
 
   DEBUGF(infof(data, "SSH DISCONNECT is done\n"));