]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
wolfssh: fix freeing of resources in disconnect
authorStefan Eissing <stefan@eissing.org>
Tue, 11 Mar 2025 09:04:50 +0000 (10:04 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 11 Mar 2025 13:56:38 +0000 (14:56 +0100)
ssh's disconnect assumed that the session to the server could be
shut down successfully during disconnect. When this failed, e.g.
timed out, memory was leaked.

Closes #16668

lib/vssh/wolfssh.c

index d799da6aa3aa8be62a21752ccf3ff00649c135fd..031b55da91aab532e8d5c26525a9178113141403 100644 (file)
@@ -70,6 +70,7 @@ static int wssh_getsock(struct Curl_easy *data,
                         curl_socket_t *sock);
 static CURLcode wssh_setup_connection(struct Curl_easy *data,
                                       struct connectdata *conn);
+static void wssh_sshc_cleanup(struct ssh_conn *sshc, struct Curl_easy *data);
 
 #if 0
 /*
@@ -367,7 +368,7 @@ static int userauth(byte authtype,
 static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
 {
   struct connectdata *conn = data->conn;
-  struct ssh_conn *sshc;
+  struct ssh_conn *sshc = &conn->proto.sshc;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   int rc;
 
@@ -387,7 +388,6 @@ static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
     conn->recv[FIRSTSOCKET] = wsftp_recv;
     conn->send[FIRSTSOCKET] = wsftp_send;
   }
-  sshc = &conn->proto.sshc;
   sshc->ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
   if(!sshc->ctx) {
     failf(data, "No wolfSSH context");
@@ -428,8 +428,7 @@ static CURLcode wssh_connect(struct Curl_easy *data, bool *done)
 
   return wssh_multi_statemach(data, done);
 error:
-  wolfSSH_free(sshc->ssh_session);
-  wolfSSH_CTX_free(sshc->ctx);
+  wssh_sshc_cleanup(sshc, data);
   return CURLE_FAILED_INIT;
 }
 
@@ -892,9 +891,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
       return CURLE_SSH;
 
     case SSH_SFTP_SHUTDOWN:
-      Curl_safefree(sshc->homedir);
-      wolfSSH_free(sshc->ssh_session);
-      wolfSSH_CTX_free(sshc->ctx);
+      wssh_sshc_cleanup(sshc, data);
       state(data, SSH_STOP);
       return CURLE_OK;
     default:
@@ -1064,6 +1061,20 @@ static CURLcode wssh_done(struct Curl_easy *data, CURLcode status)
   return result;
 }
 
+static void wssh_sshc_cleanup(struct ssh_conn *sshc, struct Curl_easy *data)
+{
+  (void)data;
+  if(sshc->ssh_session) {
+    wolfSSH_free(sshc->ssh_session);
+    sshc->ssh_session = NULL;
+  }
+  if(sshc->ctx) {
+    wolfSSH_CTX_free(sshc->ctx);
+    sshc->ctx = NULL;
+  }
+  Curl_safefree(sshc->homedir);
+}
+
 #if 0
 static CURLcode wscp_done(struct Curl_easy *data,
                          CURLcode code, bool premature)
@@ -1089,11 +1100,10 @@ static CURLcode wscp_doing(struct Curl_easy *data,
 static CURLcode wscp_disconnect(struct Curl_easy *data,
                                 struct connectdata *conn, bool dead_connection)
 {
+  struct ssh_conn *sshc = &conn->proto.sshc;
   CURLcode result = CURLE_OK;
-  (void)data;
-  (void)conn;
   (void)dead_connection;
-
+  wssh_sshc_cleanup(sshc, data);
   return result;
 }
 #endif
@@ -1122,6 +1132,7 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data,
                                  struct connectdata *conn,
                                  bool dead)
 {
+  struct ssh_conn *sshc = &conn->proto.sshc;
   CURLcode result = CURLE_OK;
   (void)dead;
 
@@ -1133,6 +1144,7 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data,
     result = wssh_block_statemach(data, TRUE);
   }
 
+  wssh_sshc_cleanup(sshc, data);
   DEBUGF(infof(data, "SSH DISCONNECT is done"));
   return result;
 }