From 1b3cda0bd6378de612b4db8809f443ad9d0e98d5 Mon Sep 17 00:00:00 2001 From: Henry Beberman Date: Wed, 15 Jan 2025 19:17:14 -0800 Subject: [PATCH] cmake: patch CVE-2024-11053 (#11926) Co-authored-by: jslobodzian (cherry picked from commit 51810cdc91f7f4426e31ddbb08eb8885ff3d5633) --- SPECS/cmake/CVE-2024-11053.patch | 331 ++++++++++++++++++ SPECS/cmake/cmake.spec | 6 +- .../manifests/package/toolchain_aarch64.txt | 4 +- .../manifests/package/toolchain_x86_64.txt | 4 +- 4 files changed, 340 insertions(+), 5 deletions(-) create mode 100644 SPECS/cmake/CVE-2024-11053.patch diff --git a/SPECS/cmake/CVE-2024-11053.patch b/SPECS/cmake/CVE-2024-11053.patch new file mode 100644 index 00000000000..a15c238aac2 --- /dev/null +++ b/SPECS/cmake/CVE-2024-11053.patch @@ -0,0 +1,331 @@ +From 277c4661bd10b7f513c18f84b64431dad20c2722 Mon Sep 17 00:00:00 2001 +From: Henry Beberman +Date: Wed, 15 Jan 2025 01:03:08 +0000 +Subject: [PATCH] Backport updated netrc parsing + +Backport fix for CVE-2024-11053 from upstream commit to vendored libcurl 7.77.0 + +From e9b9bbac22c26cf67316fa8e6c6b9e831af31949 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 15 Nov 2024 11:06:36 +0100 +Subject: [PATCH] netrc: address several netrc parser flaws + +- make sure that a match that returns a username also returns a + password, that should be blank if no password is found + +- fix handling of multiple logins for same host where the password/login + order might be reversed. + +- reject credentials provided in the .netrc if they contain ASCII control + codes - if the used protocol does not support such (like HTTP and WS do) + +diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c +index 13610bb..2c93c6e 100644 +--- a/Utilities/cmcurl/lib/netrc.c ++++ b/Utilities/cmcurl/lib/netrc.c +@@ -42,9 +42,19 @@ + enum host_lookup_state { + NOTHING, + HOSTFOUND, /* the 'machine' keyword was found */ +- HOSTVALID /* this is "our" machine! */ ++ HOSTVALID, /* this is "our" machine! */ ++ MACDEF + }; + ++enum found_state { ++ NONE, ++ LOGIN, ++ PASSWORD ++}; ++ ++#define FOUND_LOGIN 1 ++#define FOUND_PASSWORD 2 ++ + #define NETRC_FILE_MISSING 1 + #define NETRC_FAILED -1 + #define NETRC_SUCCESS 0 +@@ -62,16 +72,14 @@ static int parsenetrc(const char *host, + FILE *file; + int retcode = NETRC_FILE_MISSING; + char *login = *loginp; +- char *password = *passwordp; +- bool specific_login = (login && *login != 0); +- bool login_alloc = FALSE; +- bool password_alloc = FALSE; ++ char *password = NULL; ++ bool specific_login = !!login; /* points to something */ + enum host_lookup_state state = NOTHING; +- +- char state_login = 0; /* Found a login keyword */ +- char state_password = 0; /* Found a password keyword */ +- int state_our_login = FALSE; /* With specific_login, found *our* login +- name */ ++ enum found_state keyword = NONE; ++ unsigned char found = 0; /* login + password found bits, as they can come in ++ any order */ ++ bool our_login = FALSE; /* found our login name */ ++ bool done = FALSE; + + DEBUGASSERT(netrcfile); + +@@ -90,110 +98,129 @@ static int parsenetrc(const char *host, + continue; + while(tok) { + +- if((login && *login) && (password && *password)) { +- done = TRUE; +- break; +- } +- + switch(state) { +- case NOTHING: +- if(strcasecompare("machine", tok)) { +- /* the next tok is the machine name, this is in itself the +- delimiter that starts the stuff entered for this machine, +- after this we need to search for 'login' and +- 'password'. */ +- state = HOSTFOUND; +- } +- else if(strcasecompare("default", tok)) { +- state = HOSTVALID; +- retcode = NETRC_SUCCESS; /* we did find our host */ +- } +- break; +- case HOSTFOUND: +- if(strcasecompare(host, tok)) { +- /* and yes, this is our host! */ +- state = HOSTVALID; +- retcode = NETRC_SUCCESS; /* we did find our host */ +- } +- else +- /* not our host */ +- state = NOTHING; +- break; +- case HOSTVALID: +- /* we are now parsing sub-keywords concerning "our" host */ +- if(state_login) { +- if(specific_login) { +- state_our_login = strcasecompare(login, tok); ++ case NOTHING: ++ if(strcasecompare("macdef", tok)) ++ /* Define a macro. A macro is defined with the specified name; its ++ contents begin with the next .netrc line and continue until a ++ null line (consecutive new-line characters) is encountered. */ ++ state = MACDEF; ++ else if(strcasecompare("machine", tok)) { ++ /* the next tok is the machine name, this is in itself the delimiter ++ that starts the stuff entered for this machine, after this we ++ need to search for 'login' and 'password'. */ ++ state = HOSTFOUND; ++ keyword = NONE; ++ found = 0; ++ our_login = FALSE; ++ Curl_safefree(password); ++ if(!specific_login) ++ Curl_safefree(login); + } +- else if(!login || strcmp(login, tok)) { +- if(login_alloc) { ++ else if(strcasecompare("default", tok)) { ++ state = HOSTVALID; ++ retcode = NETRC_SUCCESS; /* we did find our host */ ++ } ++ break; ++ case MACDEF: ++ if(!*tok) ++ state = NOTHING; ++ break; ++ case HOSTFOUND: ++ if(strcasecompare(host, tok)) { ++ /* and yes, this is our host! */ ++ state = HOSTVALID; ++ retcode = NETRC_SUCCESS; /* we did find our host */ ++ } ++ else ++ /* not our host */ ++ state = NOTHING; ++ break; ++ case HOSTVALID: ++ /* we are now parsing sub-keywords concerning "our" host */ ++ if(keyword == LOGIN) { ++ if(specific_login) ++ our_login = !Curl_timestrcmp(login, tok); ++ else { ++ our_login = TRUE; + free(login); +- login_alloc = FALSE; +- } +- login = strdup(tok); +- if(!login) { +- retcode = NETRC_FAILED; /* allocation failed */ +- goto out; ++ login = strdup(tok); ++ if(!login) { ++ retcode = NETRC_FAILED; /* allocation failed */ ++ goto out; ++ } + } +- login_alloc = TRUE; ++ found |= FOUND_LOGIN; ++ keyword = NONE; + } +- state_login = 0; +- } +- else if(state_password) { +- if((state_our_login || !specific_login) +- && (!password || strcmp(password, tok))) { +- if(password_alloc) { +- free(password); +- password_alloc = FALSE; +- } ++ else if(keyword == PASSWORD) { ++ free(password); + password = strdup(tok); + if(!password) { + retcode = NETRC_FAILED; /* allocation failed */ + goto out; + } +- password_alloc = TRUE; ++ if(!specific_login || our_login) ++ found |= FOUND_PASSWORD; ++ keyword = NONE; ++ } ++ else if(strcasecompare("login", tok)) ++ keyword = LOGIN; ++ else if(strcasecompare("password", tok)) ++ keyword = PASSWORD; ++ else if(strcasecompare("machine", tok)) { ++ /* a new machine here */ ++ if(found & FOUND_PASSWORD) { ++ done = TRUE; ++ break; ++ } ++ state = HOSTFOUND; ++ keyword = NONE; ++ found = 0; ++ Curl_safefree(password); ++ if(!specific_login) ++ Curl_safefree(login); ++ } ++ else if(strcasecompare("default", tok)) { ++ state = HOSTVALID; ++ retcode = NETRC_SUCCESS; /* we did find our host */ ++ Curl_safefree(password); ++ if(!specific_login) ++ Curl_safefree(login); ++ } ++ if((found == (FOUND_PASSWORD|FOUND_LOGIN)) && our_login) { ++ done = TRUE; ++ break; + } +- state_password = 0; +- } +- else if(strcasecompare("login", tok)) +- state_login = 1; +- else if(strcasecompare("password", tok)) +- state_password = 1; +- else if(strcasecompare("machine", tok)) { +- /* ok, there's machine here go => */ +- state = HOSTFOUND; +- state_our_login = FALSE; +- } +- break; +- } /* switch (state) */ ++ break; ++ } /* switch (state) */ + + tok = strtok_r(NULL, " \t\n", &tok_buf); + } /* while(tok) */ + } /* while fgets() */ + + out: ++ if(!retcode) { ++ if(!password && our_login) { ++ /* success without a password, set a blank one */ ++ password = strdup(""); ++ if(!password) ++ retcode = 1; /* out of memory */ ++ } ++ else if(!login && !password) ++ /* a default with no credentials */ ++ retcode = NETRC_FILE_MISSING; ++ } + if(!retcode) { + /* success */ +- *login_changed = FALSE; +- *password_changed = FALSE; +- if(login_alloc) { +- if(*loginp) +- free(*loginp); ++ if(!specific_login) + *loginp = login; +- *login_changed = TRUE; +- } +- if(password_alloc) { +- if(*passwordp) +- free(*passwordp); +- *passwordp = password; +- *password_changed = TRUE; +- } ++ *passwordp = password; + } + else { +- if(login_alloc) ++ if(!specific_login) + free(login); +- if(password_alloc) +- free(password); ++ free(password); + } + fclose(file); + } +diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c +index 1ee38af..28ab55a 100644 +--- a/Utilities/cmcurl/lib/url.c ++++ b/Utilities/cmcurl/lib/url.c +@@ -2890,23 +2890,25 @@ static CURLcode override_login(struct Curl_easy *data, + bool netrc_passwd_changed = FALSE; + int ret; + +- ret = Curl_parsenetrc(conn->host.name, +- userp, passwdp, +- &netrc_user_changed, &netrc_passwd_changed, +- data->set.str[STRING_NETRC_FILE]); +- if(ret > 0) { +- infof(data, "Couldn't find host %s in the %s file; using defaults\n", +- conn->host.name, data->set.str[STRING_NETRC_FILE]); +- } +- else if(ret < 0) { +- return CURLE_OUT_OF_MEMORY; +- } +- else { +- /* set bits.netrc TRUE to remember that we got the name from a .netrc +- file, so that it is safe to use even if we followed a Location: to a +- different host or similar. */ +- conn->bits.netrc = TRUE; +- conn->bits.user_passwd = TRUE; /* enable user+password */ ++ if(!*passwdp) { ++ ret = Curl_parsenetrc(conn->host.name, ++ userp, passwdp, ++ &netrc_user_changed, &netrc_passwd_changed, ++ data->set.str[STRING_NETRC_FILE]); ++ if(ret > 0) { ++ infof(data, "Couldn't find host %s in the %s file; using defaults\n", ++ conn->host.name, data->set.str[STRING_NETRC_FILE]); ++ } ++ else if(ret < 0) { ++ return CURLE_OUT_OF_MEMORY; ++ } ++ else { ++ /* set bits.netrc TRUE to remember that we got the name from a .netrc ++ file, so that it is safe to use even if we followed a Location: to a ++ different host or similar. */ ++ conn->bits.netrc = TRUE; ++ conn->bits.user_passwd = TRUE; /* enable user+password */ ++ } + } + } + +-- +2.45.2 + diff --git a/SPECS/cmake/cmake.spec b/SPECS/cmake/cmake.spec index 8a7d542b887..65c02607088 100644 --- a/SPECS/cmake/cmake.spec +++ b/SPECS/cmake/cmake.spec @@ -2,7 +2,7 @@ Summary: Cmake Name: cmake Version: 3.21.4 -Release: 14%{?dist} +Release: 15%{?dist} License: BSD AND LGPLv2+ Vendor: Microsoft Corporation Distribution: Mariner @@ -32,6 +32,7 @@ Patch17: CVE-2023-46218.patch Patch18: CVE-2024-2398.patch Patch19: CVE-2024-28182.patch Patch20: CVE-2024-7264.patch +Patch21: CVE-2024-11053.patch BuildRequires: bzip2 BuildRequires: bzip2-devel BuildRequires: curl @@ -97,6 +98,9 @@ bin/ctest --force-new-ctest-process --rerun-failed --output-on-failure %{_prefix}/doc/%{name}-*/* %changelog +* Tue Jan 14 2025 Henry Beberman - 3.21.4-15 +- Patch vendored curl for CVE-2024-11053 + * Thu Nov 21 2024 Vince Perri - 3.21.4-14 - Patch CVE-2024-2398 and CVE-2024-7264 (bundled curl) - Patch CVE-2024-28182 (bundled nghttp2) diff --git a/toolkit/resources/manifests/package/toolchain_aarch64.txt b/toolkit/resources/manifests/package/toolchain_aarch64.txt index 202be2d6b47..eb493367daa 100644 --- a/toolkit/resources/manifests/package/toolchain_aarch64.txt +++ b/toolkit/resources/manifests/package/toolchain_aarch64.txt @@ -30,8 +30,8 @@ check-debuginfo-0.15.2-1.cm2.aarch64.rpm chkconfig-1.20-4.cm2.aarch64.rpm chkconfig-debuginfo-1.20-4.cm2.aarch64.rpm chkconfig-lang-1.20-4.cm2.aarch64.rpm -cmake-3.21.4-14.cm2.aarch64.rpm -cmake-debuginfo-3.21.4-14.cm2.aarch64.rpm +cmake-3.21.4-15.cm2.aarch64.rpm +cmake-debuginfo-3.21.4-15.cm2.aarch64.rpm coreutils-8.32-7.cm2.aarch64.rpm coreutils-debuginfo-8.32-7.cm2.aarch64.rpm coreutils-lang-8.32-7.cm2.aarch64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_x86_64.txt b/toolkit/resources/manifests/package/toolchain_x86_64.txt index 6bd2210fb72..55d702e769e 100644 --- a/toolkit/resources/manifests/package/toolchain_x86_64.txt +++ b/toolkit/resources/manifests/package/toolchain_x86_64.txt @@ -31,8 +31,8 @@ check-debuginfo-0.15.2-1.cm2.x86_64.rpm chkconfig-1.20-4.cm2.x86_64.rpm chkconfig-debuginfo-1.20-4.cm2.x86_64.rpm chkconfig-lang-1.20-4.cm2.x86_64.rpm -cmake-3.21.4-14.cm2.x86_64.rpm -cmake-debuginfo-3.21.4-14.cm2.x86_64.rpm +cmake-3.21.4-15.cm2.x86_64.rpm +cmake-debuginfo-3.21.4-15.cm2.x86_64.rpm coreutils-8.32-7.cm2.x86_64.rpm coreutils-debuginfo-8.32-7.cm2.x86_64.rpm coreutils-lang-8.32-7.cm2.x86_64.rpm