From: Stefan Eissing Date: Tue, 11 Mar 2025 09:04:50 +0000 (+0100) Subject: wolfssh: fix freeing of resources in disconnect X-Git-Tag: curl-8_13_0~175 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=763fa529df91ab46fb8c03f00b221a8b046d80d4;p=thirdparty%2Fcurl.git wolfssh: fix freeing of resources in disconnect 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 --- diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index d799da6aa3..031b55da91 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -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; }