回退 'Pull Request !25 : CVE-2023-27534 安全更新'

This commit is contained in:
zhaikangning 2023-10-24 06:47:41 +00:00 committed by Gitee
parent a68d38f682
commit 8cd3e9bd97
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
1 changed files with 36 additions and 35 deletions

View File

@ -30,8 +30,6 @@
#include "escape.h" #include "escape.h"
#include "memdebug.h" #include "memdebug.h"
#define MAX_SSHPATH_LEN 100000 /* arbitrary */
/* figure out the path to work with in this particular request */ /* figure out the path to work with in this particular request */
CURLcode Curl_getworkingpath(struct connectdata *conn, CURLcode Curl_getworkingpath(struct connectdata *conn,
char *homedir, /* when SFTP is used */ char *homedir, /* when SFTP is used */
@ -39,57 +37,60 @@ CURLcode Curl_getworkingpath(struct connectdata *conn,
real path to work with */ real path to work with */
{ {
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
char *real_path = NULL;
char *working_path; char *working_path;
size_t working_path_len; size_t working_path_len;
struct dynbuf npath;
CURLcode result = CURLcode result =
Curl_urldecode(data, data->state.up.path, 0, &working_path, Curl_urldecode(data, data->state.up.path, 0, &working_path,
&working_path_len, FALSE); &working_path_len, FALSE);
if(result) if(result)
return result; return result;
/* new path to switch to in case we need to */
Curl_dyn_init(&npath, MAX_SSHPATH_LEN);
/* Check for /~/, indicating relative to the user's home directory */ /* Check for /~/, indicating relative to the user's home directory */
if((data->conn->handler->protocol & CURLPROTO_SCP) && if(conn->handler->protocol & CURLPROTO_SCP) {
(working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) { real_path = malloc(working_path_len + 1);
/* It is referenced to the home directory, so strip the leading '/~/' */ if(real_path == NULL) {
if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) {
free(working_path); free(working_path);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
/* It is referenced to the home directory, so strip the leading '/~/' */
memcpy(real_path, working_path + 3, working_path_len - 2);
else
memcpy(real_path, working_path, 1 + working_path_len);
} }
else if((data->conn->handler->protocol & CURLPROTO_SFTP) && else if(conn->handler->protocol & CURLPROTO_SFTP) {
(working_path_len > 2) && !memcmp(working_path, "/~/", 3)) { if((working_path_len > 1) && (working_path[1] == '~')) {
size_t len; size_t homelen = strlen(homedir);
const char *p; real_path = malloc(homelen + working_path_len + 1);
int copyfrom = 3; if(real_path == NULL) {
if(Curl_dyn_add(&npath, homedir)) { free(working_path);
free(working_path); return CURLE_OUT_OF_MEMORY;
return CURLE_OUT_OF_MEMORY; }
/* It is referenced to the home directory, so strip the
leading '/' */
memcpy(real_path, homedir, homelen);
real_path[homelen] = '/';
real_path[homelen + 1] = '\0';
if(working_path_len > 3) {
memcpy(real_path + homelen + 1, working_path + 3,
1 + working_path_len -3);
}
} }
/* Copy a separating '/' if homedir does not end with one */ else {
len = Curl_dyn_len(&npath); real_path = malloc(working_path_len + 1);
p = Curl_dyn_ptr(&npath); if(real_path == NULL) {
if(len && (p[len-1] != '/')) free(working_path);
copyfrom = 2; return CURLE_OUT_OF_MEMORY;
}
if(Curl_dyn_addn(&npath, memcpy(real_path, working_path, 1 + working_path_len);
&working_path[copyfrom], working_path_len - copyfrom)) {
free(working_path);
return CURLE_OUT_OF_MEMORY;
} }
} }
if(Curl_dyn_len(&npath)) { free(working_path);
free(working_path);
/* store the pointer for the caller to receive */ /* store the pointer for the caller to receive */
*path = Curl_dyn_ptr(&npath); *path = real_path;
}
else
*path = working_path;
return CURLE_OK; return CURLE_OK;
} }