diff --git a/base/comps/curl/CVE-2026-12064.patch b/base/comps/curl/CVE-2026-12064.patch new file mode 100644 index 00000000000..01dc2351813 --- /dev/null +++ b/base/comps/curl/CVE-2026-12064.patch @@ -0,0 +1,278 @@ +From 97c239fba29744a73385a1748a72203d50719bc9 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Mon, 6 Jul 2026 03:26:08 +0000 +Subject: [PATCH] config2setopts: use default protocol properly + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference AI Backport of: https://github.com/curl/curl/commit/ab3bb8cd8be8f9d4acb97da041.patch +--- + docs/cmdline-opts/proto-default.md | 37 +++++++++++++-------- + src/config2setopts.c | 41 ++++++++++++++++------- + tests/data/Makefile.am | 2 +- + tests/data/test1724 | 53 ++++++++++++++++++++++++++++++ + tests/data/test1725 | 29 ++++++++++++++++ + tests/data/test2036 | 26 +++++++++++++++ + 6 files changed, 162 insertions(+), 26 deletions(-) + create mode 100644 tests/data/test1724 + create mode 100644 tests/data/test1725 + create mode 100644 tests/data/test2036 + +diff --git a/docs/cmdline-opts/proto-default.md b/docs/cmdline-opts/proto-default.md +index 209e5cd..08005f2 100644 +--- a/docs/cmdline-opts/proto-default.md ++++ b/docs/cmdline-opts/proto-default.md +@@ -1,22 +1,30 @@ ++ ++ + --- + c: Copyright (C) Daniel Stenberg, , et al. + SPDX-License-Identifier: curl +-Long: proto-default +-Help: Use PROTOCOL for any URL missing a scheme +-Arg: +-Added: 7.45.0 +-Category: connection curl +-Multi: single +-See-also: +- - proto +- - proto-redir +-Example: +- - --proto-default https ftp.example.com ++Title: --proto-default ++Section: 3 + --- + +-# `--proto-default` ++# NAME ++ ++proto-default - set default protocol + +-Use *protocol* for any provided URL missing a scheme. ++# SYNOPSIS ++ ++~~~sh ++--proto-default ++~~~ ++ ++# DESCRIPTION ++ ++Use *protocol* for any provided URL missing a scheme. The case-insensitive ++name should be given without any `://` suffix. + + An unknown or unsupported protocol causes error *CURLE_UNSUPPORTED_PROTOCOL*. + +@@ -24,3 +32,6 @@ This option does not change the default proxy protocol (http). + + Without this option set, curl guesses protocol based on the hostname, see + --url for details. ++ ++The default protocol cannot be set to `ipfs` or `ipns`. Those schemes need to ++be used explicitly in the URL. +diff --git a/src/config2setopts.c b/src/config2setopts.c +index 8e4af65..fd7db06 100644 +--- a/src/config2setopts.c ++++ b/src/config2setopts.c +@@ -138,15 +138,31 @@ static CURLcode url_proto_and_rewrite(char **url, + DEBUGASSERT(url && *url); + if(uh) { + char *schemep = NULL; +- if(!curl_url_set(uh, CURLUPART_URL, *url, +- CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME) && +- !curl_url_get(uh, CURLUPART_SCHEME, &schemep, +- CURLU_DEFAULT_SCHEME)) { +-#ifdef CURL_DISABLE_IPFS +- (void)config; +-#else +- if(curl_strequal(schemep, proto_ipfs) || +- curl_strequal(schemep, proto_ipns)) { ++ CURLUcode uc; ++ uc = curl_url_set(uh, CURLUPART_URL, *url, ++ CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME); ++ if(!uc) { ++ if(config->proto_default) { ++ /* when a default proto is requested, do not guess */ ++ uc = curl_url_get(uh, CURLUPART_SCHEME, &schemep, ++ CURLU_NO_GUESS_SCHEME); ++ if(uc == CURLUE_NO_SCHEME) { ++ /* use the default */ ++ proto = proto_token(config->proto_default); ++ if(proto) ++ uc = CURLUE_OK; ++ } ++ } ++ else { ++ uc = curl_url_get(uh, CURLUPART_SCHEME, &schemep, ++ CURLU_DEFAULT_SCHEME); ++ } ++ if(schemep) ++ proto = proto_token(schemep); ++#ifndef CURL_DISABLE_IPFS ++ if(!uc && ++ (curl_strequal(schemep, proto_ipfs) || ++ curl_strequal(schemep, proto_ipns))) { + result = ipfs_url_rewrite(uh, schemep, url, config); + /* short-circuit proto_token, we know it is ipfs or ipns */ + if(curl_strequal(schemep, proto_ipfs)) +@@ -156,12 +172,13 @@ static CURLcode url_proto_and_rewrite(char **url, + if(result) + config->synthetic_error = TRUE; + } +- else + #endif /* !CURL_DISABLE_IPFS */ +- proto = proto_token(schemep); +- ++ if(uc == CURLUE_OUT_OF_MEMORY) ++ result = CURLE_OUT_OF_MEMORY; + curl_free(schemep); + } ++ else if(uc == CURLUE_OUT_OF_MEMORY) ++ result = CURLE_OUT_OF_MEMORY; + curl_url_cleanup(uh); + } + else +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 7d8e8c7..d78e87b 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -244,7 +244,7 @@ test2000 test2001 test2002 test2003 test2004 test2005 \ + \ + test2023 \ + test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ +-test2032 test2033 test2034 test2035 test2037 test2038 test2039 \ ++test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \ + test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \ + test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ + test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ +diff --git a/tests/data/test1724 b/tests/data/test1724 +new file mode 100644 +index 0000000..3cd328e +--- /dev/null ++++ b/tests/data/test1724 +@@ -0,0 +1,53 @@ ++ ++ ++ ++ ++IPFS ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT ++ETag: "21025-dc7-39462498" ++Accept-Ranges: bytes ++Content-Length: 21 ++Connection: close ++Content-Type: text/plain ++Funny-head: yesyes ++ ++Hello curl from IPFS ++ ++ ++ ++# Client-side ++ ++ ++ipfs ++ ++ ++http ++ ++ ++IPFS with --proto-default HTTP ++ ++ ++--ipfs-gateway http://%HOSTIP:%HTTPPORT ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u --proto-default http ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++User-Agent: curl/%VERSION ++Accept: */* ++ ++ ++ ++ +diff --git a/tests/data/test1725 b/tests/data/test1725 +new file mode 100644 +index 0000000..2a882c7 +--- /dev/null ++++ b/tests/data/test1725 +@@ -0,0 +1,29 @@ ++ ++ ++ ++ ++SCP ++server key check ++ ++ ++ ++# Client-side ++ ++ ++scp ++ ++ ++SCP incorrect host key with --proto-default SCP ++ ++ ++--hostpubmd5 00000000000000000000000000000000 --key %LOGDIR/server/curl_client_key --pubkey %LOGDIR/server/curl_client_key.pub -u %USER: %HOSTIP:%SSHPORT%SCP_PWD/%LOGDIR/irrelevant-file --insecure --proto-default SCP ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++60 ++ ++ ++ +diff --git a/tests/data/test2036 b/tests/data/test2036 +new file mode 100644 +index 0000000..b017a71 +--- /dev/null ++++ b/tests/data/test2036 +@@ -0,0 +1,26 @@ ++ ++ ++ ++ ++--proto-default ++ ++ ++ ++# Client-side ++ ++ ++Attempt to set a default protocol with :// suffix ++ ++ ++--proto-default https:// ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# CURLE_UNSUPPORTED_PROTOCOL is error code 1 ++ ++1 ++ ++ ++ +-- +2.45.4 + diff --git a/base/comps/curl/CVE-2026-8927.patch b/base/comps/curl/CVE-2026-8927.patch new file mode 100644 index 00000000000..06bdafa9341 --- /dev/null +++ b/base/comps/curl/CVE-2026-8927.patch @@ -0,0 +1,295 @@ +From 1cdf54d6bc42e23b07f0d9917d5438683607fdd5 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Mon, 6 Jul 2026 03:30:29 +0000 +Subject: [PATCH] url: detect proxy changes read from environment + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference AI Backport of: https://github.com/curl/curl/commit/5c225384b8d52c6.patch +--- + lib/url.c | 11 ++++ + tests/data/test1647 | 103 +++++++++++++++++++++++++++++++ + tests/libtest/Makefile.inc | 1 + + tests/libtest/lib1647.c | 120 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 235 insertions(+) + create mode 100644 tests/data/test1647 + create mode 100644 tests/libtest/lib1647.c + +diff --git a/lib/url.c b/lib/url.c +index e4f250f..8b94725 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -344,6 +344,9 @@ CURLcode Curl_close(struct Curl_easy **datap) + Curl_freeset(data); + Curl_headers_cleanup(data); + Curl_netrc_cleanup(&data->state.netrc); ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ Curl_safefree(data->state.envproxy); ++#endif + free(data); + return CURLE_OK; + } +@@ -2581,6 +2584,14 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, + result = CURLE_UNSUPPORTED_PROTOCOL; + goto out; + #else ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ if(!Curl_safecmp(data->state.envproxy, proxy)) { ++ /* proxy changed */ ++ Curl_auth_digest_cleanup(&data->state.proxydigest); ++ Curl_safefree(data->state.envproxy); ++ data->state.envproxy = strdup(proxy); ++ } ++#endif + /* force this connection's protocol to become HTTP if compatible */ + if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) { + if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) && +diff --git a/tests/data/test1647 b/tests/data/test1647 +new file mode 100644 +index 0000000..a87487f +--- /dev/null ++++ b/tests/data/test1647 +@@ -0,0 +1,103 @@ ++ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++HTTP proxy Digest auth ++multi ++ ++ ++ ++# Server-side ++ ++ ++# this is returned first since we get no proxy-auth ++ ++HTTP/1.1 407 Authorization Required to proxy me my dear ++Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345" ++Content-Length: 33 ++ ++And you should ignore this data. ++ ++ ++# then this is returned when we get proxy-auth ++ ++HTTP/1.1 200 OK ++Content-Length: 21 ++Server: no ++ ++Nice proxy auth sir! ++ ++ ++ ++HTTP/1.1 401 OK ++Content-Length: 21 ++Server: no ++ ++Denied access. Leave ++ ++ ++ ++ ++# Client-side ++ ++ ++http ++https-proxy ++https ++ ++# tool is what to use instead of 'curl' ++ ++lib%TESTNUMBER ++ ++ ++!SSPI ++crypto ++proxy ++digest ++Debug ++ ++ ++http_proxy=%HOSTIP:%HTTPPORT ++https_proxy=https://%HOSTIP:%HTTPSPROXYPORT ++CURL_ENTROPY=99376 ++ ++ ++HTTP proxy auth Digest, then change proxy with env var and do it again ++ ++ ++http://test.remote.example.com/path/%TESTNUMBER https://another.example.com:%HTTPSPORT/ daniel:monkey123 another:bump456 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Proxy-Authorization: Digest username="daniel", realm="weirdorealm", nonce="12345", uri="/path/%TESTNUMBER", response="7a1672891aff03248887b1a6674b8096" ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ ++CONNECT another.example.com:%HTTPSPORT HTTP/1.1 ++Host: another.example.com:%HTTPSPORT ++Proxy-Connection: Keep-Alive ++ ++ ++ ++# CONNECT fails ++ ++7 ++ ++ ++ +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc +index 8878ae8..474a25f 100644 +--- a/tests/libtest/Makefile.inc ++++ b/tests/libtest/Makefile.inc +@@ -78,6 +78,7 @@ TESTS_C = \ + lib1576.c \ + lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c \ + lib1598.c lib1599.c \ ++ lib1647.c \ + lib1662.c \ + lib1900.c lib1901.c lib1903.c lib1905.c lib1906.c lib1907.c \ + lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c \ +diff --git a/tests/libtest/lib1647.c b/tests/libtest/lib1647.c +new file mode 100644 +index 0000000..8060e1b +--- /dev/null ++++ b/tests/libtest/lib1647.c +@@ -0,0 +1,120 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, , et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++/* ++ * argv1 = the first URL ++ * argv2 = URL2 ++ * argv3 = credentials 1 ++ * argv4 = credentials 2 ++ */ ++ ++#include "first.h" ++ ++/* this is meant to pick up the proxy from the environment variable */ ++static CURLcode init1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ res_easy_setopt(curl, CURLOPT_URL, url); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_VERBOSE, 1L); ++ if(result) ++ goto init_failed; ++ ++ return CURLE_OK; /* success */ ++ ++init_failed: ++ return result; /* failure */ ++} ++ ++static CURLcode run1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ result = init1647(curl, url, userpwd); ++ if(result) ++ return result; ++ ++ return curl_easy_perform(curl); ++} ++ ++static CURLcode test_lib1647(const char *URL) ++{ ++ CURLcode result = CURLE_OK; ++ CURL *curl = NULL; ++ ++ res_global_init(CURL_GLOBAL_ALL); ++ if(result) ++ return result; ++ ++ curl = curl_easy_init(); ++ if(!curl) { ++ curl_mfprintf(stderr, "curl_easy_init() failed\n"); ++ curl_global_cleanup(); ++ return TEST_ERR_MAJOR_BAD; ++ } ++ ++ start_test_timing(); ++ ++ curl_mprintf("--- First get '%s'\n", URL); ++ result = run1647(curl, URL, libtest_arg3); ++ if(result) ++ goto test_cleanup; ++ ++ curl_mprintf("--- Then get '%s'\n", libtest_arg2); ++ result = run1647(curl, libtest_arg2, libtest_arg4); ++ ++test_cleanup: ++ ++ /* proper cleanup sequence - type PB */ ++ ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ return result; ++} +-- +2.45.4 + diff --git a/base/comps/curl/CVE-2026-9547.patch b/base/comps/curl/CVE-2026-9547.patch new file mode 100644 index 00000000000..d20efb83d6c --- /dev/null +++ b/base/comps/curl/CVE-2026-9547.patch @@ -0,0 +1,33 @@ +From 57c2df47c6230a7727633c3975dae5830352b786 Mon Sep 17 00:00:00 2001 +From: Joshua Rogers +Date: Fri, 22 May 2026 09:48:15 +0200 +Subject: [PATCH] libssh: map SSH_KNOWN_HOSTS_OTHER to CURLKHMATCH_MISMATCH + +Host key type mismatch from libssh was incorrectly reported as missing, +causing key callbacks to accept instead of reject. + +Reported by: Joshua Rogers (Aisle Research) +Closes #21724 + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/curl/curl/commit/0b8dbbc63c98777e4584cb9fbd71df3464008ad1.patch +--- + lib/vssh/libssh.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c +index 3bae943..11c9c28 100644 +--- a/lib/vssh/libssh.c ++++ b/lib/vssh/libssh.c +@@ -423,6 +423,8 @@ static int myssh_is_known(struct Curl_easy *data, struct ssh_conn *sshc) + keymatch = CURLKHMATCH_OK; + break; + case SSH_KNOWN_HOSTS_OTHER: ++ keymatch = CURLKHMATCH_MISMATCH; ++ break; + case SSH_KNOWN_HOSTS_NOT_FOUND: + case SSH_KNOWN_HOSTS_UNKNOWN: + case SSH_KNOWN_HOSTS_ERROR: +-- +2.45.4 + diff --git a/base/comps/curl/curl.comp.toml b/base/comps/curl/curl.comp.toml index 1bdfeb364d1..79683e27f97 100644 --- a/base/comps/curl/curl.comp.toml +++ b/base/comps/curl/curl.comp.toml @@ -1,4 +1,5 @@ [components.curl] +release = { calculation = "manual" } [[components.curl.overlays]] description = "Drop python3-impacket BuildRequires (only used by Fedora-gated upstream test 1451; python-impacket is not packaged for Azure Linux due to RPM-signing issues)" @@ -14,3 +15,34 @@ description = "Annotate the now-empty %if 0%{?fedora} block to make the AZL devi type = "spec-search-replace" regex = '^# needed for upstream test 1451$' replacement = '# python3-impacket BuildRequires intentionally omitted in Azure Linux — see curl.comp.toml overlay (RPM signing blocker; test 1451 is Fedora-gated)' + +[[components.curl.overlays]] +description = "Fix CVE-2026-12064 — https://github.com/curl/curl/commit/ab3bb8cd8be8f9d4acb97da041.patch" +type = "patch-add" +source = "CVE-2026-12064.patch" + +[[components.curl.overlays]] +description = "Fix CVE-2026-8927 — https://github.com/curl/curl/commit/5c225384b8d52c6.patch" +type = "patch-add" +source = "CVE-2026-8927.patch" + +[[components.curl.overlays]] +description = "Fix CVE-2026-9547 — https://github.com/curl/curl/commit/0b8dbbc63c98777e4584cb9fbd71df3464008ad1.patch" +type = "patch-add" +source = "CVE-2026-9547.patch" + +[[components.curl.overlays]] +description = "Bump release for CVE-2026-12064, CVE-2026-8927, CVE-2026-9547" +type = "spec-set-tag" +tag = "Release" +value = "8%{?dist}" + +[[components.curl.overlays]] +description = "Add changelog entry for CVE-2026-12064, CVE-2026-8927, CVE-2026-9547" +type = "spec-prepend-lines" +section = "%changelog" +lines = [ + "* Mon Jul 06 2026 Azure Linux Security Servicing Account - 8.15.0-8", + "- Patch for CVE-2026-12064, CVE-2026-8927, CVE-2026-9547", + "", +] diff --git a/locks/curl.lock b/locks/curl.lock index 03e206dffc8..24d50a06c37 100644 --- a/locks/curl.lock +++ b/locks/curl.lock @@ -2,5 +2,5 @@ version = 1 import-commit = '0e4af6147551051527b731925d55c37b164260d5' upstream-commit = '0e4af6147551051527b731925d55c37b164260d5' -input-fingerprint = 'sha256:e12a3388d48de45bc572148ab3264d55cb991514bb820e37eada4fc3ee220650' +input-fingerprint = 'sha256:3ef07f10d1e5314c59a6f305b108cb746ac232ee6850ca8690470eb219705ede' resolution-input-hash = 'sha256:466421704711c4fd3c71f0b2ed715a0e61d49e3e26f3a2637fee755795849c8e' diff --git a/specs/c/curl/CVE-2026-12064.patch b/specs/c/curl/CVE-2026-12064.patch new file mode 100644 index 00000000000..01dc2351813 --- /dev/null +++ b/specs/c/curl/CVE-2026-12064.patch @@ -0,0 +1,278 @@ +From 97c239fba29744a73385a1748a72203d50719bc9 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Mon, 6 Jul 2026 03:26:08 +0000 +Subject: [PATCH] config2setopts: use default protocol properly + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference AI Backport of: https://github.com/curl/curl/commit/ab3bb8cd8be8f9d4acb97da041.patch +--- + docs/cmdline-opts/proto-default.md | 37 +++++++++++++-------- + src/config2setopts.c | 41 ++++++++++++++++------- + tests/data/Makefile.am | 2 +- + tests/data/test1724 | 53 ++++++++++++++++++++++++++++++ + tests/data/test1725 | 29 ++++++++++++++++ + tests/data/test2036 | 26 +++++++++++++++ + 6 files changed, 162 insertions(+), 26 deletions(-) + create mode 100644 tests/data/test1724 + create mode 100644 tests/data/test1725 + create mode 100644 tests/data/test2036 + +diff --git a/docs/cmdline-opts/proto-default.md b/docs/cmdline-opts/proto-default.md +index 209e5cd..08005f2 100644 +--- a/docs/cmdline-opts/proto-default.md ++++ b/docs/cmdline-opts/proto-default.md +@@ -1,22 +1,30 @@ ++ ++ + --- + c: Copyright (C) Daniel Stenberg, , et al. + SPDX-License-Identifier: curl +-Long: proto-default +-Help: Use PROTOCOL for any URL missing a scheme +-Arg: +-Added: 7.45.0 +-Category: connection curl +-Multi: single +-See-also: +- - proto +- - proto-redir +-Example: +- - --proto-default https ftp.example.com ++Title: --proto-default ++Section: 3 + --- + +-# `--proto-default` ++# NAME ++ ++proto-default - set default protocol + +-Use *protocol* for any provided URL missing a scheme. ++# SYNOPSIS ++ ++~~~sh ++--proto-default ++~~~ ++ ++# DESCRIPTION ++ ++Use *protocol* for any provided URL missing a scheme. The case-insensitive ++name should be given without any `://` suffix. + + An unknown or unsupported protocol causes error *CURLE_UNSUPPORTED_PROTOCOL*. + +@@ -24,3 +32,6 @@ This option does not change the default proxy protocol (http). + + Without this option set, curl guesses protocol based on the hostname, see + --url for details. ++ ++The default protocol cannot be set to `ipfs` or `ipns`. Those schemes need to ++be used explicitly in the URL. +diff --git a/src/config2setopts.c b/src/config2setopts.c +index 8e4af65..fd7db06 100644 +--- a/src/config2setopts.c ++++ b/src/config2setopts.c +@@ -138,15 +138,31 @@ static CURLcode url_proto_and_rewrite(char **url, + DEBUGASSERT(url && *url); + if(uh) { + char *schemep = NULL; +- if(!curl_url_set(uh, CURLUPART_URL, *url, +- CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME) && +- !curl_url_get(uh, CURLUPART_SCHEME, &schemep, +- CURLU_DEFAULT_SCHEME)) { +-#ifdef CURL_DISABLE_IPFS +- (void)config; +-#else +- if(curl_strequal(schemep, proto_ipfs) || +- curl_strequal(schemep, proto_ipns)) { ++ CURLUcode uc; ++ uc = curl_url_set(uh, CURLUPART_URL, *url, ++ CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME); ++ if(!uc) { ++ if(config->proto_default) { ++ /* when a default proto is requested, do not guess */ ++ uc = curl_url_get(uh, CURLUPART_SCHEME, &schemep, ++ CURLU_NO_GUESS_SCHEME); ++ if(uc == CURLUE_NO_SCHEME) { ++ /* use the default */ ++ proto = proto_token(config->proto_default); ++ if(proto) ++ uc = CURLUE_OK; ++ } ++ } ++ else { ++ uc = curl_url_get(uh, CURLUPART_SCHEME, &schemep, ++ CURLU_DEFAULT_SCHEME); ++ } ++ if(schemep) ++ proto = proto_token(schemep); ++#ifndef CURL_DISABLE_IPFS ++ if(!uc && ++ (curl_strequal(schemep, proto_ipfs) || ++ curl_strequal(schemep, proto_ipns))) { + result = ipfs_url_rewrite(uh, schemep, url, config); + /* short-circuit proto_token, we know it is ipfs or ipns */ + if(curl_strequal(schemep, proto_ipfs)) +@@ -156,12 +172,13 @@ static CURLcode url_proto_and_rewrite(char **url, + if(result) + config->synthetic_error = TRUE; + } +- else + #endif /* !CURL_DISABLE_IPFS */ +- proto = proto_token(schemep); +- ++ if(uc == CURLUE_OUT_OF_MEMORY) ++ result = CURLE_OUT_OF_MEMORY; + curl_free(schemep); + } ++ else if(uc == CURLUE_OUT_OF_MEMORY) ++ result = CURLE_OUT_OF_MEMORY; + curl_url_cleanup(uh); + } + else +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 7d8e8c7..d78e87b 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -244,7 +244,7 @@ test2000 test2001 test2002 test2003 test2004 test2005 \ + \ + test2023 \ + test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \ +-test2032 test2033 test2034 test2035 test2037 test2038 test2039 \ ++test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \ + test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \ + test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ + test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ +diff --git a/tests/data/test1724 b/tests/data/test1724 +new file mode 100644 +index 0000000..3cd328e +--- /dev/null ++++ b/tests/data/test1724 +@@ -0,0 +1,53 @@ ++ ++ ++ ++ ++IPFS ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT ++ETag: "21025-dc7-39462498" ++Accept-Ranges: bytes ++Content-Length: 21 ++Connection: close ++Content-Type: text/plain ++Funny-head: yesyes ++ ++Hello curl from IPFS ++ ++ ++ ++# Client-side ++ ++ ++ipfs ++ ++ ++http ++ ++ ++IPFS with --proto-default HTTP ++ ++ ++--ipfs-gateway http://%HOSTIP:%HTTPPORT ipfs://bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u --proto-default http ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++GET /ipfs/bafybeidecnvkrygux6uoukouzps5ofkeevoqland7kopseiod6pzqvjg7u HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++User-Agent: curl/%VERSION ++Accept: */* ++ ++ ++ ++ +diff --git a/tests/data/test1725 b/tests/data/test1725 +new file mode 100644 +index 0000000..2a882c7 +--- /dev/null ++++ b/tests/data/test1725 +@@ -0,0 +1,29 @@ ++ ++ ++ ++ ++SCP ++server key check ++ ++ ++ ++# Client-side ++ ++ ++scp ++ ++ ++SCP incorrect host key with --proto-default SCP ++ ++ ++--hostpubmd5 00000000000000000000000000000000 --key %LOGDIR/server/curl_client_key --pubkey %LOGDIR/server/curl_client_key.pub -u %USER: %HOSTIP:%SSHPORT%SCP_PWD/%LOGDIR/irrelevant-file --insecure --proto-default SCP ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++60 ++ ++ ++ +diff --git a/tests/data/test2036 b/tests/data/test2036 +new file mode 100644 +index 0000000..b017a71 +--- /dev/null ++++ b/tests/data/test2036 +@@ -0,0 +1,26 @@ ++ ++ ++ ++ ++--proto-default ++ ++ ++ ++# Client-side ++ ++ ++Attempt to set a default protocol with :// suffix ++ ++ ++--proto-default https:// ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# CURLE_UNSUPPORTED_PROTOCOL is error code 1 ++ ++1 ++ ++ ++ +-- +2.45.4 + diff --git a/specs/c/curl/CVE-2026-8927.patch b/specs/c/curl/CVE-2026-8927.patch new file mode 100644 index 00000000000..06bdafa9341 --- /dev/null +++ b/specs/c/curl/CVE-2026-8927.patch @@ -0,0 +1,295 @@ +From 1cdf54d6bc42e23b07f0d9917d5438683607fdd5 Mon Sep 17 00:00:00 2001 +From: AllSpark +Date: Mon, 6 Jul 2026 03:30:29 +0000 +Subject: [PATCH] url: detect proxy changes read from environment + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference AI Backport of: https://github.com/curl/curl/commit/5c225384b8d52c6.patch +--- + lib/url.c | 11 ++++ + tests/data/test1647 | 103 +++++++++++++++++++++++++++++++ + tests/libtest/Makefile.inc | 1 + + tests/libtest/lib1647.c | 120 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 235 insertions(+) + create mode 100644 tests/data/test1647 + create mode 100644 tests/libtest/lib1647.c + +diff --git a/lib/url.c b/lib/url.c +index e4f250f..8b94725 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -344,6 +344,9 @@ CURLcode Curl_close(struct Curl_easy **datap) + Curl_freeset(data); + Curl_headers_cleanup(data); + Curl_netrc_cleanup(&data->state.netrc); ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ Curl_safefree(data->state.envproxy); ++#endif + free(data); + return CURLE_OK; + } +@@ -2581,6 +2584,14 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, + result = CURLE_UNSUPPORTED_PROTOCOL; + goto out; + #else ++#ifndef CURL_DISABLE_DIGEST_AUTH ++ if(!Curl_safecmp(data->state.envproxy, proxy)) { ++ /* proxy changed */ ++ Curl_auth_digest_cleanup(&data->state.proxydigest); ++ Curl_safefree(data->state.envproxy); ++ data->state.envproxy = strdup(proxy); ++ } ++#endif + /* force this connection's protocol to become HTTP if compatible */ + if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) { + if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) && +diff --git a/tests/data/test1647 b/tests/data/test1647 +new file mode 100644 +index 0000000..a87487f +--- /dev/null ++++ b/tests/data/test1647 +@@ -0,0 +1,103 @@ ++ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++HTTP proxy Digest auth ++multi ++ ++ ++ ++# Server-side ++ ++ ++# this is returned first since we get no proxy-auth ++ ++HTTP/1.1 407 Authorization Required to proxy me my dear ++Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345" ++Content-Length: 33 ++ ++And you should ignore this data. ++ ++ ++# then this is returned when we get proxy-auth ++ ++HTTP/1.1 200 OK ++Content-Length: 21 ++Server: no ++ ++Nice proxy auth sir! ++ ++ ++ ++HTTP/1.1 401 OK ++Content-Length: 21 ++Server: no ++ ++Denied access. Leave ++ ++ ++ ++ ++# Client-side ++ ++ ++http ++https-proxy ++https ++ ++# tool is what to use instead of 'curl' ++ ++lib%TESTNUMBER ++ ++ ++!SSPI ++crypto ++proxy ++digest ++Debug ++ ++ ++http_proxy=%HOSTIP:%HTTPPORT ++https_proxy=https://%HOSTIP:%HTTPSPROXYPORT ++CURL_ENTROPY=99376 ++ ++ ++HTTP proxy auth Digest, then change proxy with env var and do it again ++ ++ ++http://test.remote.example.com/path/%TESTNUMBER https://another.example.com:%HTTPSPORT/ daniel:monkey123 another:bump456 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://test.remote.example.com/path/%TESTNUMBER HTTP/1.1 ++Host: test.remote.example.com ++Proxy-Authorization: Digest username="daniel", realm="weirdorealm", nonce="12345", uri="/path/%TESTNUMBER", response="7a1672891aff03248887b1a6674b8096" ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ ++CONNECT another.example.com:%HTTPSPORT HTTP/1.1 ++Host: another.example.com:%HTTPSPORT ++Proxy-Connection: Keep-Alive ++ ++ ++ ++# CONNECT fails ++ ++7 ++ ++ ++ +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc +index 8878ae8..474a25f 100644 +--- a/tests/libtest/Makefile.inc ++++ b/tests/libtest/Makefile.inc +@@ -78,6 +78,7 @@ TESTS_C = \ + lib1576.c \ + lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c \ + lib1598.c lib1599.c \ ++ lib1647.c \ + lib1662.c \ + lib1900.c lib1901.c lib1903.c lib1905.c lib1906.c lib1907.c \ + lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c \ +diff --git a/tests/libtest/lib1647.c b/tests/libtest/lib1647.c +new file mode 100644 +index 0000000..8060e1b +--- /dev/null ++++ b/tests/libtest/lib1647.c +@@ -0,0 +1,120 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) Daniel Stenberg, , et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at https://curl.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ * SPDX-License-Identifier: curl ++ * ++ ***************************************************************************/ ++/* ++ * argv1 = the first URL ++ * argv2 = URL2 ++ * argv3 = credentials 1 ++ * argv4 = credentials 2 ++ */ ++ ++#include "first.h" ++ ++/* this is meant to pick up the proxy from the environment variable */ ++static CURLcode init1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ res_easy_setopt(curl, CURLOPT_URL, url); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L); ++ if(result) ++ goto init_failed; ++ ++ res_easy_setopt(curl, CURLOPT_VERBOSE, 1L); ++ if(result) ++ goto init_failed; ++ ++ return CURLE_OK; /* success */ ++ ++init_failed: ++ return result; /* failure */ ++} ++ ++static CURLcode run1647(CURL *curl, const char *url, const char *userpwd) ++{ ++ CURLcode result = CURLE_OK; ++ ++ result = init1647(curl, url, userpwd); ++ if(result) ++ return result; ++ ++ return curl_easy_perform(curl); ++} ++ ++static CURLcode test_lib1647(const char *URL) ++{ ++ CURLcode result = CURLE_OK; ++ CURL *curl = NULL; ++ ++ res_global_init(CURL_GLOBAL_ALL); ++ if(result) ++ return result; ++ ++ curl = curl_easy_init(); ++ if(!curl) { ++ curl_mfprintf(stderr, "curl_easy_init() failed\n"); ++ curl_global_cleanup(); ++ return TEST_ERR_MAJOR_BAD; ++ } ++ ++ start_test_timing(); ++ ++ curl_mprintf("--- First get '%s'\n", URL); ++ result = run1647(curl, URL, libtest_arg3); ++ if(result) ++ goto test_cleanup; ++ ++ curl_mprintf("--- Then get '%s'\n", libtest_arg2); ++ result = run1647(curl, libtest_arg2, libtest_arg4); ++ ++test_cleanup: ++ ++ /* proper cleanup sequence - type PB */ ++ ++ curl_easy_cleanup(curl); ++ curl_global_cleanup(); ++ return result; ++} +-- +2.45.4 + diff --git a/specs/c/curl/CVE-2026-9547.patch b/specs/c/curl/CVE-2026-9547.patch new file mode 100644 index 00000000000..d20efb83d6c --- /dev/null +++ b/specs/c/curl/CVE-2026-9547.patch @@ -0,0 +1,33 @@ +From 57c2df47c6230a7727633c3975dae5830352b786 Mon Sep 17 00:00:00 2001 +From: Joshua Rogers +Date: Fri, 22 May 2026 09:48:15 +0200 +Subject: [PATCH] libssh: map SSH_KNOWN_HOSTS_OTHER to CURLKHMATCH_MISMATCH + +Host key type mismatch from libssh was incorrectly reported as missing, +causing key callbacks to accept instead of reject. + +Reported by: Joshua Rogers (Aisle Research) +Closes #21724 + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/curl/curl/commit/0b8dbbc63c98777e4584cb9fbd71df3464008ad1.patch +--- + lib/vssh/libssh.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c +index 3bae943..11c9c28 100644 +--- a/lib/vssh/libssh.c ++++ b/lib/vssh/libssh.c +@@ -423,6 +423,8 @@ static int myssh_is_known(struct Curl_easy *data, struct ssh_conn *sshc) + keymatch = CURLKHMATCH_OK; + break; + case SSH_KNOWN_HOSTS_OTHER: ++ keymatch = CURLKHMATCH_MISMATCH; ++ break; + case SSH_KNOWN_HOSTS_NOT_FOUND: + case SSH_KNOWN_HOSTS_UNKNOWN: + case SSH_KNOWN_HOSTS_ERROR: +-- +2.45.4 + diff --git a/specs/c/curl/curl.spec b/specs/c/curl/curl.spec index 4465af45493..f21f03b0693 100644 --- a/specs/c/curl/curl.spec +++ b/specs/c/curl/curl.spec @@ -10,7 +10,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 8.15.0 -Release: 7%{?dist} +Release: 8%{?dist} License: curl Source0: https://curl.se/download/%{name}-%{version_no_tilde}.tar.xz Source1: https://curl.se/download/%{name}-%{version_no_tilde}.tar.xz.asc @@ -165,6 +165,9 @@ Requires: libcurl%{?_isa} >= %{version}-%{release} # (we need to translate 3.0.0-alpha16 -> 3.0.0-0.alpha16 and 3.0.0-beta1 -> 3.0.0-0.beta1 though) %global openssl_version %({ pkg-config --modversion openssl 2>/dev/null || echo 0;} | sed 's|-|-0.|') +Patch106: CVE-2026-12064.patch +Patch107: CVE-2026-8927.patch +Patch108: CVE-2026-9547.patch %description curl is a command line tool for transferring data with URL syntax, supporting FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, @@ -423,6 +426,9 @@ rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/wcurl.1* %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal %changelog +* Mon Jul 06 2026 Azure Linux Security Servicing Account - 8.15.0-8 +- Patch for CVE-2026-12064, CVE-2026-8927, CVE-2026-9547 + * Mon Jan 19 2026 Jan Macku - 8.15.0-5 - fix broken TLS options for threaded LDAPS (CVE-2025-14017)