]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
libssh/libssh2: reject quote command lines with too much data
authorDaniel Stenberg <daniel@haxx.se>
Sun, 12 Oct 2025 09:05:46 +0000 (11:05 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 12 Oct 2025 13:34:27 +0000 (15:34 +0200)
If there is lingering letters left on the right side after the paths
have been parsed, they are syntactically incorrect so returning error is
the safe thing to do.

Reported-by: Harry Sintonen
Closes #19030

lib/vssh/libssh.c
lib/vssh/libssh2.c

index 544e682b771e261a5140cbad89e284bce8664dcd..69666c53884fabe023b5323854538cf33e65cc18 100644 (file)
@@ -1557,6 +1557,18 @@ static int myssh_in_SFTP_POSTQUOTE_INIT(struct Curl_easy *data,
   return SSH_NO_ERROR;
 }
 
+static int return_quote_error(struct Curl_easy *data,
+                              struct ssh_conn *sshc)
+{
+  failf(data, "Suspicious data after the command line");
+  Curl_safefree(sshc->quote_path1);
+  Curl_safefree(sshc->quote_path2);
+  myssh_to(data, sshc, SSH_SFTP_CLOSE);
+  sshc->nextstate = SSH_NO_STATE;
+  sshc->actualcode = CURLE_QUOTE_ERROR;
+  return SSH_NO_ERROR;
+}
+
 static int myssh_in_SFTP_QUOTE(struct Curl_easy *data,
                                struct ssh_conn *sshc,
                                struct SSHPROTO *sshp)
@@ -1665,6 +1677,8 @@ static int myssh_in_SFTP_QUOTE(struct Curl_easy *data,
       sshc->actualcode = result;
       return SSH_NO_ERROR;
     }
+    if(*cp)
+      return return_quote_error(data, sshc);
     sshc->quote_attrs = NULL;
     myssh_to(data, sshc, SSH_SFTP_QUOTE_STAT);
     return SSH_NO_ERROR;
@@ -1686,10 +1700,14 @@ static int myssh_in_SFTP_QUOTE(struct Curl_easy *data,
       sshc->actualcode = result;
       return SSH_NO_ERROR;
     }
+    if(*cp)
+      return return_quote_error(data, sshc);
     myssh_to(data, sshc, SSH_SFTP_QUOTE_SYMLINK);
     return SSH_NO_ERROR;
   }
   else if(!strncmp(cmd, "mkdir ", 6)) {
+    if(*cp)
+      return return_quote_error(data, sshc);
     /* create dir */
     myssh_to(data, sshc, SSH_SFTP_QUOTE_MKDIR);
     return SSH_NO_ERROR;
@@ -1710,20 +1728,28 @@ static int myssh_in_SFTP_QUOTE(struct Curl_easy *data,
       sshc->actualcode = result;
       return SSH_NO_ERROR;
     }
+    if(*cp)
+      return return_quote_error(data, sshc);
     myssh_to(data, sshc, SSH_SFTP_QUOTE_RENAME);
     return SSH_NO_ERROR;
   }
   else if(!strncmp(cmd, "rmdir ", 6)) {
     /* delete dir */
+    if(*cp)
+      return return_quote_error(data, sshc);
     myssh_to(data, sshc, SSH_SFTP_QUOTE_RMDIR);
     return SSH_NO_ERROR;
   }
   else if(!strncmp(cmd, "rm ", 3)) {
+    if(*cp)
+      return return_quote_error(data, sshc);
     myssh_to(data, sshc, SSH_SFTP_QUOTE_UNLINK);
     return SSH_NO_ERROR;
   }
 #ifdef HAS_STATVFS_SUPPORT
   else if(!strncmp(cmd, "statvfs ", 8)) {
+    if(*cp)
+      return return_quote_error(data, sshc);
     myssh_to(data, sshc, SSH_SFTP_QUOTE_STATVFS);
     return SSH_NO_ERROR;
   }
index a92e7508d519b9dddc14c732c15cb0304db749f6..ad416aba8e0009ad356d0b13d62610ff1dfcba19 100644 (file)
@@ -843,6 +843,15 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data,
   return result;
 }
 
+static CURLcode return_quote_error(struct Curl_easy *data,
+                                   struct ssh_conn *sshc)
+{
+  failf(data, "Suspicious data after the command line");
+  Curl_safefree(sshc->quote_path1);
+  Curl_safefree(sshc->quote_path2);
+  return CURLE_QUOTE_ERROR;
+}
+
 static CURLcode sftp_quote(struct Curl_easy *data,
                            struct ssh_conn *sshc,
                            struct SSHPROTO *sshp)
@@ -930,6 +939,9 @@ static CURLcode sftp_quote(struct Curl_easy *data,
       Curl_safefree(sshc->quote_path1);
       return result;
     }
+    if(*cp)
+      return_quote_error(data, sshc);
+
     memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
     myssh_state(data, sshc, SSH_SFTP_QUOTE_STAT);
     return result;
@@ -946,10 +958,14 @@ static CURLcode sftp_quote(struct Curl_easy *data,
       Curl_safefree(sshc->quote_path1);
       return result;
     }
+    if(*cp)
+      return_quote_error(data, sshc);
     myssh_state(data, sshc, SSH_SFTP_QUOTE_SYMLINK);
     return result;
   }
   else if(!strncmp(cmd, "mkdir ", 6)) {
+    if(*cp)
+      return_quote_error(data, sshc);
     /* create dir */
     myssh_state(data, sshc, SSH_SFTP_QUOTE_MKDIR);
     return result;
@@ -965,19 +981,27 @@ static CURLcode sftp_quote(struct Curl_easy *data,
       Curl_safefree(sshc->quote_path1);
       return result;
     }
+    if(*cp)
+      return_quote_error(data, sshc);
     myssh_state(data, sshc, SSH_SFTP_QUOTE_RENAME);
     return result;
   }
   else if(!strncmp(cmd, "rmdir ", 6)) {
+    if(*cp)
+      return_quote_error(data, sshc);
     /* delete dir */
     myssh_state(data, sshc, SSH_SFTP_QUOTE_RMDIR);
     return result;
   }
   else if(!strncmp(cmd, "rm ", 3)) {
+    if(*cp)
+      return_quote_error(data, sshc);
     myssh_state(data, sshc, SSH_SFTP_QUOTE_UNLINK);
     return result;
   }
   else if(!strncmp(cmd, "statvfs ", 8)) {
+    if(*cp)
+      return_quote_error(data, sshc);
     myssh_state(data, sshc, SSH_SFTP_QUOTE_STATVFS);
     return result;
   }