]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ftp/sftp: strdup data info memory
authorStefan Eissing <stefan@eissing.org>
Sat, 15 Mar 2025 10:20:15 +0000 (11:20 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 15 Mar 2025 20:49:38 +0000 (21:49 +0100)
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

lib/ftp.c
lib/url.c
lib/vssh/libssh.c
lib/vssh/libssh2.c

index 50e3e5273844f4477a9bbb806899d7af7fdd1ca7..cdb9b0e4e7d3d3e1d558e3833a727fdace11296d 100644 (file)
--- 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);
index d3250e0dcb0cc5de6c7fe7cbc544b0b04cf7800d..ffabad59cf7fe63d1b6ed0852138ddc80d4a857e 100644 (file)
--- 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);
 
index 8a08d81615ce315dd617798a7941d0da42135fd7..299b7c8c3e333e031ca981fcd6eb3d33bb9be495 100644 (file)
@@ -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();
index b5e2ac7ae0d92a7bf3a611bcebf4e997fb8eab1f..2447d1ddf90d858a6992882fe77ad574d08e4018 100644 (file)
@@ -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;