From 8cd3e9bd97fd9d196e439ddb5523405b5908e34a Mon Sep 17 00:00:00 2001 From: zhaikangning <857458455@qq.com> Date: Tue, 24 Oct 2023 06:47:41 +0000 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E9=80=80=20'Pull=20Request=20!25=20:?= =?UTF-8?q?=20CVE-2023-27534=20=E5=AE=89=E5=85=A8=E6=9B=B4=E6=96=B0'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/curl_path.c | 71 +++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/lib/curl_path.c b/lib/curl_path.c index 99366223b..f42963463 100644 --- a/lib/curl_path.c +++ b/lib/curl_path.c @@ -30,8 +30,6 @@ #include "escape.h" #include "memdebug.h" - -#define MAX_SSHPATH_LEN 100000 /* arbitrary */ /* figure out the path to work with in this particular request */ CURLcode Curl_getworkingpath(struct connectdata *conn, char *homedir, /* when SFTP is used */ @@ -39,57 +37,60 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, real path to work with */ { struct Curl_easy *data = conn->data; + char *real_path = NULL; char *working_path; size_t working_path_len; - struct dynbuf npath; CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &working_path, &working_path_len, FALSE); if(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 */ - if((data->conn->handler->protocol & CURLPROTO_SCP) && - (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) { - /* It is referenced to the home directory, so strip the leading '/~/' */ - if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) { + if(conn->handler->protocol & CURLPROTO_SCP) { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { free(working_path); 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) && - (working_path_len > 2) && !memcmp(working_path, "/~/", 3)) { - size_t len; - const char *p; - int copyfrom = 3; - if(Curl_dyn_add(&npath, homedir)) { - free(working_path); - return CURLE_OUT_OF_MEMORY; + else if(conn->handler->protocol & CURLPROTO_SFTP) { + if((working_path_len > 1) && (working_path[1] == '~')) { + size_t homelen = strlen(homedir); + real_path = malloc(homelen + working_path_len + 1); + if(real_path == NULL) { + free(working_path); + 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 */ - len = Curl_dyn_len(&npath); - p = Curl_dyn_ptr(&npath); - if(len && (p[len-1] != '/')) - copyfrom = 2; - - if(Curl_dyn_addn(&npath, - &working_path[copyfrom], working_path_len - copyfrom)) { - free(working_path); - return CURLE_OUT_OF_MEMORY; + else { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + memcpy(real_path, working_path, 1 + working_path_len); } } - if(Curl_dyn_len(&npath)) { - free(working_path); + free(working_path); - /* store the pointer for the caller to receive */ - *path = Curl_dyn_ptr(&npath); - } - else - *path = working_path; + /* store the pointer for the caller to receive */ + *path = real_path; return CURLE_OK; }