From: Stefan Eissing Date: Sat, 15 Mar 2025 10:20:15 +0000 (+0100) Subject: ftp/sftp: strdup data info memory X-Git-Tag: curl-8_13_0~127 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebce3f0c02a78c1b440516654ad2d3a91dffa2fc;p=thirdparty%2Fcurl.git ftp/sftp: strdup data info memory Fix the broken implementation to have `data->state` carry pointers into connectdata members. Always dup the memory and free when easy handle closes. Closes #16733 --- diff --git a/lib/ftp.c b/lib/ftp.c index 50e3e52738..cdb9b0e4e7 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -2906,7 +2906,10 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, ftpc->entrypath = dir; /* remember this */ infof(data, "Entry path is '%s'", ftpc->entrypath); /* also save it where getinfo can access it: */ - data->state.most_recent_ftp_entrypath = ftpc->entrypath; + free(data->state.most_recent_ftp_entrypath); + data->state.most_recent_ftp_entrypath = strdup(ftpc->entrypath); + if(!data->state.most_recent_ftp_entrypath) + return CURLE_OUT_OF_MEMORY; ftp_state(data, FTP_SYST); break; } @@ -2915,7 +2918,10 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, ftpc->entrypath = dir; /* remember this */ infof(data, "Entry path is '%s'", ftpc->entrypath); /* also save it where getinfo can access it: */ - data->state.most_recent_ftp_entrypath = ftpc->entrypath; + free(data->state.most_recent_ftp_entrypath); + data->state.most_recent_ftp_entrypath = strdup(ftpc->entrypath); + if(!data->state.most_recent_ftp_entrypath) + return CURLE_OUT_OF_MEMORY; } else { /* could not get the path */ @@ -4095,16 +4101,10 @@ static CURLcode ftp_disconnect(struct Curl_easy *data, /* The FTP session may or may not have been allocated/setup at this point! */ (void)ftp_quit(data, conn); /* ignore errors on the QUIT */ - if(ftpc->entrypath) { - if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { - data->state.most_recent_ftp_entrypath = NULL; - } - Curl_safefree(ftpc->entrypath); - } - freedirs(ftpc); Curl_safefree(ftpc->account); Curl_safefree(ftpc->alternative_to_user); + Curl_safefree(ftpc->entrypath); Curl_safefree(ftpc->prevpath); Curl_safefree(ftpc->server_os); Curl_pp_disconnect(pp); diff --git a/lib/url.c b/lib/url.c index d3250e0dcb..ffabad59cf 100644 --- a/lib/url.c +++ b/lib/url.c @@ -285,6 +285,7 @@ CURLcode Curl_close(struct Curl_easy **datap) #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) Curl_http_auth_cleanup_digest(data); #endif + Curl_safefree(data->state.most_recent_ftp_entrypath); Curl_safefree(data->info.contenttype); Curl_safefree(data->info.wouldredirect); diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 8a08d81615..299b7c8c3e 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -944,7 +944,10 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); break; } - data->state.most_recent_ftp_entrypath = sshc->homedir; + free(data->state.most_recent_ftp_entrypath); + data->state.most_recent_ftp_entrypath = strdup(sshc->homedir); + if(!data->state.most_recent_ftp_entrypath) + return CURLE_OUT_OF_MEMORY; /* This is the last step in the SFTP connect phase. Do note that while we get the homedir here, we get the "workingpath" in the DO action @@ -1763,7 +1766,6 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } SSH_STRING_FREE_CHAR(sshc->homedir); - data->state.most_recent_ftp_entrypath = NULL; state(data, SSH_SESSION_DISCONNECT); break; @@ -1939,7 +1941,6 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } SSH_STRING_FREE_CHAR(sshc->homedir); - data->state.most_recent_ftp_entrypath = NULL; state(data, SSH_SESSION_FREE); FALLTHROUGH(); diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index b5e2ac7ae0..2447d1ddf9 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -2008,7 +2008,10 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - data->state.most_recent_ftp_entrypath = sshc->homedir; + free(data->state.most_recent_ftp_entrypath); + data->state.most_recent_ftp_entrypath = strdup(sshc->homedir); + if(!data->state.most_recent_ftp_entrypath) + return CURLE_OUT_OF_MEMORY; } else { /* Return the error type */ @@ -2591,7 +2594,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) } Curl_safefree(sshc->homedir); - data->state.most_recent_ftp_entrypath = NULL; state(data, SSH_SESSION_DISCONNECT); break; @@ -2857,7 +2859,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) } Curl_safefree(sshc->homedir); - data->state.most_recent_ftp_entrypath = NULL; state(data, SSH_SESSION_FREE); break;