From: Daniel Stenberg Date: Sun, 12 Oct 2025 09:05:46 +0000 (+0200) Subject: libssh/libssh2: reject quote command lines with too much data X-Git-Tag: rc-8_17_0-2~104 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=578706addec3d41cb5db64160d23795a95ca11d9;p=thirdparty%2Fcurl.git libssh/libssh2: reject quote command lines with too much data 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 --- diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 544e682b77..69666c5388 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -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; } diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index a92e7508d5..ad416aba8e 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -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; }