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
This commit is contained in:
Daniel Stenberg 2025-10-12 11:05:46 +02:00
parent 2b49d17cba
commit 578706adde
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
2 changed files with 50 additions and 0 deletions

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

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