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
This commit is contained in:
Stefan Eissing 2025-03-11 10:04:50 +01:00 committed by Daniel Stenberg
parent 9710aec8f8
commit 763fa529df
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View 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;
}