From 5fea4588b8c5ea7655e5d56f52b88de0b56a5057 Mon Sep 17 00:00:00 2001 From: sherlock2010 <15151851377@163.com> Date: Fri, 8 Dec 2023 03:48:17 +0000 Subject: [PATCH] fix CVE-2023-46218 CVE-2023-46219 --- backport-0001-CVE-2023-46218.patch | 43 +++++++++ backport-0001-CVE-2023-46219.patch | 134 +++++++++++++++++++++++++++++ backport-0002-CVE-2023-46218.patch | 52 +++++++++++ backport-0002-CVE-2023-46219.patch | 80 +++++++++++++++++ curl.spec | 12 ++- 5 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2023-46218.patch create mode 100644 backport-0001-CVE-2023-46219.patch create mode 100644 backport-0002-CVE-2023-46218.patch create mode 100644 backport-0002-CVE-2023-46219.patch diff --git a/backport-0001-CVE-2023-46218.patch b/backport-0001-CVE-2023-46218.patch new file mode 100644 index 0000000..1280fb3 --- /dev/null +++ b/backport-0001-CVE-2023-46218.patch @@ -0,0 +1,43 @@ +From f7aeff58a369d3cd2caac4f3becd7c683ba900c7 Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Fri, 12 Mar 2021 02:34:03 +0100 +Subject: [PATCH] cookies: Fix potential NULL pointer deref with PSL + +Curl_cookie_init can be called with data being NULL, and this can in turn +be passed to Curl_cookie_add, meaning that both functions must be careful +to only use data where it's checked for being a NULL pointer. The libpsl +support code does however dereference data without checking, so if we are +indeed having an unset data pointer we cannot PSL check the cookiedomain. + +This is currently not a reachable dereference, as the only caller with a +NULL data isn't passing a file to initialize cookies from, but since the +API has this contract let's ensure we hold it. + +Closes #6731 +Reviewed-by: Daniel Stenberg + +Conflict:NA +Reference:https://github.com/curl/curl/commit/f7aeff58a369d3cd2caac4f3becd7c683ba900c7 +--- + lib/cookie.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 09fd092ac3da25..c7229c001a86d1 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -951,8 +951,12 @@ Curl_cookie_add(struct Curl_easy *data, + remove_expired(c); + + #ifdef USE_LIBPSL +- /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ +- if(domain && co->domain && !isip(co->domain)) { ++ /* ++ * Check if the domain is a Public Suffix and if yes, ignore the cookie. We ++ * must also check that the data handle isn't NULL since the psl code will ++ * dereference it. ++ */ ++ if(data && (domain && co->domain && !isip(co->domain))) { + const psl_ctx_t *psl = Curl_psl_use(data); + int acceptable; + diff --git a/backport-0001-CVE-2023-46219.patch b/backport-0001-CVE-2023-46219.patch new file mode 100644 index 0000000..5f7483c --- /dev/null +++ b/backport-0001-CVE-2023-46219.patch @@ -0,0 +1,134 @@ +From 73b65e94f3531179de45c6f3c836a610e3d0a846 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 23 Nov 2023 08:23:17 +0100 +Subject: [PATCH] fopen: create short(er) temporary file name + +Only using random letters in the name plus a ".tmp" extension. Not by +appending characters to the final file name. + +Reported-by: Maksymilian Arciemowicz + +Closes #12388 + +Conflict:Curl_rand_alnum -> Curl_rand_hex +Context adapt +Reference:https://github.com/curl/curl/commit/73b65e94f3531179de45c6f3c836a610e3d0a846 +--- + lib/fopen.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 60 insertions(+), 5 deletions(-) + +diff --git a/lib/fopen.c b/lib/fopen.c +index 75b8a7aa5..a73ac068e 100644 +--- a/lib/fopen.c ++++ b/lib/fopen.c +@@ -39,6 +39,51 @@ + #include "curl_memory.h" + #include "memdebug.h" + ++/* ++ The dirslash() function breaks a null-terminated pathname string into ++ directory and filename components then returns the directory component up ++ to, *AND INCLUDING*, a final '/'. If there is no directory in the path, ++ this instead returns a "" string. ++ ++ This function returns a pointer to malloc'ed memory. ++ ++ The input path to this function is expected to have a file name part. ++*/ ++ ++#ifdef _WIN32 ++#define PATHSEP "\\" ++#define IS_SEP(x) (((x) == '/') || ((x) == '\\')) ++#elif defined(MSDOS) || defined(__EMX__) || defined(OS2) ++#define PATHSEP "\\" ++#define IS_SEP(x) ((x) == '\\') ++#else ++#define PATHSEP "/" ++#define IS_SEP(x) ((x) == '/') ++#endif ++ ++static char *dirslash(const char *path) ++{ ++ size_t n; ++ struct dynbuf out; ++ DEBUGASSERT(path); ++ Curl_dyn_init(&out, CURL_MAX_INPUT_LENGTH); ++ n = strlen(path); ++ if(n) { ++ /* find the rightmost path separator, if any */ ++ while(n && !IS_SEP(path[n-1])) ++ --n; ++ /* skip over all the path separators, if any */ ++ while(n && IS_SEP(path[n-1])) ++ --n; ++ } ++ if(Curl_dyn_addn(&out, path, n)) ++ return NULL; ++ /* if there was a directory, append a single trailing slash */ ++ if(n && Curl_dyn_addn(&out, PATHSEP, 1)) ++ return NULL; ++ return Curl_dyn_ptr(&out); ++} ++ + /* + * Curl_fopen() opens a file for writing with a temp name, to be renamed + * to the final name when completed. If there is an existing file using this +@@ -50,25 +95,34 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, + FILE **fh, char **tempname) + { + CURLcode result = CURLE_WRITE_ERROR; +- unsigned char randsuffix[9]; ++ unsigned char randbuf[41]; + char *tempstore = NULL; + struct_stat sb; + int fd = -1; ++ char *dir; + *tempname = NULL; + ++ dir = dirslash(filename); ++ if(!dir) ++ goto fail; ++ + *fh = fopen(filename, FOPEN_WRITETEXT); + if(!*fh) + goto fail; +- if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) ++ if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { ++ free(dir); + return CURLE_OK; ++ } + fclose(*fh); + *fh = NULL; + +- result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix)); ++ result = Curl_rand_hex(data, randbuf, sizeof(randbuf)); + if(result) + goto fail; + +- tempstore = aprintf("%s.%s.tmp", filename, randsuffix); ++ /* The temp file name should not end up too long for the target file ++ system */ ++ tempstore = aprintf("%s%s.tmp", dir, randbuf); + if(!tempstore) { + result = CURLE_OUT_OF_MEMORY; + goto fail; +@@ -95,6 +149,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, + if(!*fh) + goto fail; + ++ free(dir); + *tempname = tempstore; + return CURLE_OK; + +@@ -105,7 +160,7 @@ fail: + } + + free(tempstore); +- ++ free(dir); + *tempname = NULL; + return result; + } +-- +2.33.0 + diff --git a/backport-0002-CVE-2023-46218.patch b/backport-0002-CVE-2023-46218.patch new file mode 100644 index 0000000..b2111bb --- /dev/null +++ b/backport-0002-CVE-2023-46218.patch @@ -0,0 +1,52 @@ +From 2b0994c29a721c91c572cff7808c572a24d251eb Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 23 Nov 2023 08:15:47 +0100 +Subject: [PATCH] cookie: lowercase the domain names before PSL checks + +Reported-by: Harry Sintonen + +Closes #12387 + +Conflict:acceptable = !bad_domain(domain, strlen(domain)); -> acceptable = !bad_domain(domain); +Curl_host_is_ipnum(co->domain) -> isip(co->domain) +Reference:https://github.com/curl/curl/commit/2b0994c29a721c91c572cff7808c572a24d251eb +--- + lib/cookie.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 568cf537ad1b1f..9095cea3e97f22 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -1027,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data, + * dereference it. + */ + if(data && (domain && co->domain && !isip(co->domain))) { +- const psl_ctx_t *psl = Curl_psl_use(data); +- int acceptable; +- +- if(psl) { +- acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); +- Curl_psl_release(data); ++ bool acceptable = FALSE; ++ char lcase[256]; ++ char lcookie[256]; ++ size_t dlen = strlen(domain); ++ size_t clen = strlen(co->domain); ++ if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) { ++ const psl_ctx_t *psl = Curl_psl_use(data); ++ if(psl) { ++ /* the PSL check requires lowercase domain name and pattern */ ++ Curl_strntolower(lcase, domain, dlen + 1); ++ Curl_strntolower(lcookie, co->domain, clen + 1); ++ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie); ++ Curl_psl_release(data); ++ } ++ else ++ acceptable = !bad_domain(domain); + } +- else +- acceptable = !bad_domain(domain); + + if(!acceptable) { + infof(data, "cookie '%s' dropped, domain '%s' must not " diff --git a/backport-0002-CVE-2023-46219.patch b/backport-0002-CVE-2023-46219.patch new file mode 100644 index 0000000..0c3a9f8 --- /dev/null +++ b/backport-0002-CVE-2023-46219.patch @@ -0,0 +1,80 @@ +From f27b8dba73295cb5296a50f2c19c0739b502eb94 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 24 Nov 2023 09:46:32 +0100 +Subject: [PATCH] fopen: allocate the dir after fopen + +Move the allocation of the directory name down to after the fopen() call +to allow that shortcut code path to avoid a superfluous malloc+free +cycle. + +Follow-up to 73b65e94f35311 + +Closes #12398 + +Conflict:Context adapt +Reference:https://github.com/curl/curl/commit/f27b8dba73295cb5296a50f2c19c0739b502eb94 +--- + lib/fopen.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/lib/fopen.c b/lib/fopen.c +index 2e726cc95..851279fe1 100644 +--- a/lib/fopen.c ++++ b/lib/fopen.c +@@ -99,18 +99,13 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, + char *tempstore = NULL; + struct_stat sb; + int fd = -1; +- char *dir; ++ char *dir = NULL; + *tempname = NULL; + +- dir = dirslash(filename); +- if(!dir) +- goto fail; +- + *fh = fopen(filename, FOPEN_WRITETEXT); + if(!*fh) + goto fail; + if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) { +- free(dir); + return CURLE_OK; + } + fclose(*fh); +@@ -120,9 +115,14 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, + if(result) + goto fail; + +- /* The temp file name should not end up too long for the target file +- system */ +- tempstore = aprintf("%s%s.tmp", dir, randbuf); ++ dir = dirslash(filename); ++ if(dir) { ++ /* The temp file name should not end up too long for the target file ++ system */ ++ tempstore = aprintf("%s%s.tmp", dir, randbuf); ++ free(dir); ++ } ++ + if(!tempstore) { + result = CURLE_OUT_OF_MEMORY; + goto fail; +@@ -137,7 +137,6 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename, + if(!*fh) + goto fail; + +- free(dir); + *tempname = tempstore; + return CURLE_OK; + +@@ -148,7 +147,6 @@ fail: + } + + free(tempstore); +- free(dir); + *tempname = NULL; + return result; + } +-- +2.33.0 + diff --git a/curl.spec b/curl.spec index b74ba51..082ff72 100644 --- a/curl.spec +++ b/curl.spec @@ -6,7 +6,7 @@ Name: curl Version: 7.71.1 -Release: 31 +Release: 32 Summary: Curl is used in command lines or scripts to transfer data License: MIT URL: https://curl.haxx.se/ @@ -68,6 +68,10 @@ Patch155: backport-0003-CVE-2023-28320.patch Patch156: backport-CVE-2023-32001.patch Patch157: backport-CVE-2023-38545.patch Patch158: backport-CVE-2023-38546.patch +Patch159: backport-0001-CVE-2023-46218.patch +Patch160: backport-0002-CVE-2023-46218.patch +Patch161: backport-0001-CVE-2023-46219.patch +Patch162: backport-0002-CVE-2023-46219.patch BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel BuildRequires: libidn2-devel libnghttp2-devel libpsl-devel @@ -232,6 +236,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_mandir}/man3/* %changelog +* Fri Dec 08 2023 zhouyihang - 7.71.1-32 +- Type:CVE +- CVE:CVE-2023-46218 CVE-2023-46219 +- SUG:NA +- DESC:fix CVE-2023-46218 CVE-2023-46219 + * Wed Oct 11 2023 Funda Wang - 7.71.1-31 - Type:CVE - CVE:CVE-2023-38545, CVE-2023-38546