import UBI curl-8.12.1-4.el10_2.4

This commit is contained in:
AlmaLinux RelEng Bot 2026-08-17 00:21:32 -04:00
parent 3d3dbfc08c
commit d5f4918df3
9 changed files with 939 additions and 1 deletions

View File

@ -0,0 +1,73 @@
From cd046f6c93b39d673a58c18648d8906e954c4f5d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 17 Dec 2025 10:54:16 +0100
Subject: [PATCH] openssl: toggling CURLSSLOPT_NO_PARTIALCHAIN makes a
different CA cache
Reported-by: Stanislav Fort
Closes #20009
Backported to curl 8.12.1 for RHEL 10.2
---
lib/vtls/openssl.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index a7f169d641cf..7563d9a09031 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -3488,6 +3488,7 @@ struct ossl_x509_share {
char *CAfile; /* CAfile path used to generate X509 store */
X509_STORE *store; /* cached X509 store or NULL if none */
struct curltime time; /* when the cached store was created */
+ BIT(no_partialchain); /* keep partial chain state */
};
static void oss_x509_share_free(void *key, size_t key_len, void *p)
@@ -3522,12 +3523,16 @@ ossl_cached_x509_store_expired(const struct Curl_easy *data,
static bool
ossl_cached_x509_store_different(struct Curl_cfilter *cf,
+ const struct Curl_easy *data,
const struct ossl_x509_share *mb)
{
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config =
+ Curl_ssl_cf_get_config(cf, (struct Curl_easy *)data);
+ if(mb->no_partialchain != ssl_config->no_partialchain)
+ return TRUE;
if(!mb->CAfile || !conn_config->CAfile)
return mb->CAfile != conn_config->CAfile;
-
return strcmp(mb->CAfile, conn_config->CAfile);
}
@@ -3545,7 +3550,7 @@ static X509_STORE *ossl_get_cached_x509_store(struct Curl_cfilter *cf,
sizeof(MPROTO_OSSL_X509_KEY)-1) : NULL;
if(share && share->store &&
!ossl_cached_x509_store_expired(data, share) &&
- !ossl_cached_x509_store_different(cf, share)) {
+ !ossl_cached_x509_store_different(cf, data, share)) {
store = share->store;
}
@@ -3582,6 +3587,8 @@ static void ossl_set_cached_x509_store(struct Curl_cfilter *cf,
if(X509_STORE_up_ref(store)) {
char *CAfile = NULL;
+ struct ssl_config_data *ssl_config =
+ Curl_ssl_cf_get_config(cf, (struct Curl_easy *)data);
if(conn_config->CAfile) {
CAfile = strdup(conn_config->CAfile);
@@ -3598,6 +3605,7 @@ static void ossl_set_cached_x509_store(struct Curl_cfilter *cf,
share->time = Curl_now();
share->store = store;
share->CAfile = CAfile;
+ share->no_partialchain = ssl_config->no_partialchain;
}
}
--
2.47.1

View File

@ -0,0 +1,27 @@
From 0b8dbbc63c98777e4584cb9fbd71df3464008ad1 Mon Sep 17 00:00:00 2001
From: Joshua Rogers <MegaManSec@users.noreply.github.com>
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.
Upstream-commit: 0b8dbbc63c98777e4584cb9fbd71df3464008ad1
Resolves: CVE-2026-9547
---
lib/vssh/libssh.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -429,6 +429,8 @@
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:

View File

@ -0,0 +1,81 @@
From ab3bb8cd8be8f9d4acb97da0418abc279182041e Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 12 Jun 2026 09:01:22 +0200
Subject: [PATCH] tool_operate: use default protocol properly
When --proto-default is set, use CURLU_NO_GUESS_SCHEME to avoid guessing
HTTP for schemeless URLs, and fall back to the user-specified default
protocol instead.
Adapted from upstream commit ab3bb8cd8be8f9d4acb97da0418abc279182041e
(src/config2setopts.c) for the pre-refactor src/tool_operate.c layout.
Upstream-commit: ab3bb8cd8be8f9d4acb97da0418abc279182041e
Resolves: CVE-2026-12064
---
src/tool_operate.c | 47 ++++++++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 19 deletions(-)
diff --git a/src/tool_operate.c b/src/tool_operate.c
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -784,15 +784,31 @@
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 && schemep &&
+ (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))
@@ -802,12 +818,13 @@
if(result)
config->synthetic_error = TRUE;
}
- else
-#endif /* !CURL_DISABLE_IPFS */
- proto = proto_token(schemep);
-
+#endif
+ 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

View File

@ -0,0 +1,51 @@
From a86efdd7ca5433de9231e650f18247de8319ad16 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
Date: Thu, 7 May 2026 10:30:07 +0200
Subject: [PATCH] url: fix connection reuse for starttls protocols
When a connection is tested for reuse in a transfer that *may* upgrade
to TLS (commonly via STARTTLS), the SSL configuration must match the
existing connection.
Also reject non-TLS connections when the transfer requires TLS via
STARTTLS (use_ssl >= CURLUSESSL_CONTROL).
Adapted from upstream commit a86efdd7ca5433de9231e650f18247de8319ad16
for the pre-refactor url_match_conn() layout in curl 8.12.1.
Upstream-commit: a86efdd7ca5433de9231e650f18247de8319ad16
Resolves: CVE-2026-8286
---
lib/url.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/url.c b/lib/url.c
--- a/lib/url.c
+++ b/lib/url.c
@@ -960,6 +960,13 @@
* UNLESS `conn` is the same protocol family and was upgraded to SSL. */
return FALSE;
+ /* For STARTTLS protocols that require TLS, reject non-TLS connections */
+ if(data->set.use_ssl >= CURLUSESSL_CONTROL &&
+ !(needle->handler->flags & PROTOPT_SSL) &&
+ !Curl_conn_is_ssl(conn, FIRSTSOCKET) &&
+ !conn->bits.tls_upgraded)
+ return FALSE;
+
#ifndef CURL_DISABLE_PROXY
if(needle->bits.httpproxy != conn->bits.httpproxy ||
needle->bits.socksproxy != conn->bits.socksproxy)
@@ -1094,8 +1101,9 @@
needle->remote_port != conn->remote_port)
return FALSE;
- /* If talking TLS, conn needs to use the same SSL options. */
- if((needle->handler->flags & PROTOPT_SSL) &&
+ /* If talking or upgrading to TLS, conn needs the same SSL options. */
+ if(((needle->handler->flags & PROTOPT_SSL) ||
+ data->set.use_ssl > CURLUSESSL_NONE) &&
!Curl_ssl_conn_config_match(data, conn, FALSE)) {
DEBUGF(infof(data,
"Connection #%" FMT_OFF_T

View File

@ -0,0 +1,93 @@
--- a/lib/url.c 2026-07-16 11:30:17.426896979 +0000
+++ b/lib/url.c 2026-07-16 11:30:51.002716949 +0000
@@ -847,6 +847,8 @@ struct url_conn_match {
BIT(may_multiplex);
BIT(want_ntlm_http);
BIT(want_proxy_ntlm_http);
+ BIT(want_nego_http);
+ BIT(want_proxy_nego_http);
BIT(wait_pipe);
BIT(force_reuse);
@@ -1174,6 +1176,62 @@ static bool url_match_conn(struct connec
}
#endif
+#ifdef USE_SPNEGO
+ /* If we are looking for an HTTP+Negotiate connection, check if this is
+ already authenticating with the right credentials. If not, keep looking
+ so that we can reuse Negotiate connections if possible. */
+ if(match->want_nego_http) {
+ if(conn->http_negotiate_state == GSS_AUTHNONE) {
+ /* Auth not started - safe to reuse and upgrade credentials */
+ }
+ else if(Curl_timestrcmp(needle->user, conn->user) ||
+ Curl_timestrcmp(needle->passwd, conn->passwd))
+ return FALSE;
+ }
+ else if(conn->http_negotiate_state != GSS_AUTHNONE) {
+ /* Connection is using Negotiate auth but we do not want Negotiate */
+ return FALSE;
+ }
+
+#ifndef CURL_DISABLE_PROXY
+ /* Same for Proxy Negotiate authentication */
+ if(match->want_proxy_nego_http) {
+ if(conn->proxy_negotiate_state == GSS_AUTHNONE) {
+ /* Proxy auth not started - safe to reuse and upgrade credentials */
+ }
+ else {
+ if(!conn->http_proxy.user || !conn->http_proxy.passwd)
+ return FALSE;
+
+ if(Curl_timestrcmp(needle->http_proxy.user,
+ conn->http_proxy.user) ||
+ Curl_timestrcmp(needle->http_proxy.passwd,
+ conn->http_proxy.passwd))
+ return FALSE;
+ }
+ }
+ else if(conn->proxy_negotiate_state != GSS_AUTHNONE) {
+ /* Proxy connection is using Negotiate auth but we do not want Negotiate */
+ return FALSE;
+ }
+#endif
+ if(match->want_nego_http || match->want_proxy_nego_http) {
+ /* Credentials are already checked, we may use this connection. We MUST
+ * use a connection where it has already been fully negotiated. If it has
+ * not, we keep on looking for a better one. */
+ match->found = conn;
+ if((match->want_nego_http &&
+ (conn->http_negotiate_state != GSS_AUTHNONE)) ||
+ (match->want_proxy_nego_http &&
+ (conn->proxy_negotiate_state != GSS_AUTHNONE))) {
+ /* We must use this connection, no other */
+ match->force_reuse = TRUE;
+ return TRUE;
+ }
+ return FALSE; /* get another */
+ }
+#endif
+
if(CONN_INUSE(conn)) {
DEBUGASSERT(match->may_multiplex);
DEBUGASSERT(conn->bits.multiplex);
@@ -1266,6 +1324,18 @@ ConnectionExists(struct Curl_easy *data,
#endif
#endif
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+ match.want_nego_http =
+ (data->state.authhost.want & CURLAUTH_NEGOTIATE) &&
+ (needle->handler->protocol & PROTO_FAMILY_HTTP);
+#ifndef CURL_DISABLE_PROXY
+ match.want_proxy_nego_http =
+ needle->bits.proxy_user_passwd &&
+ (data->state.authproxy.want & CURLAUTH_NEGOTIATE) &&
+ (needle->handler->protocol & PROTO_FAMILY_HTTP);
+#endif
+#endif
+
/* Find a connection in the pool that matches what "data + needle"
* requires. If a suitable candidate is found, it is attached to "data". */
result = Curl_cpool_find(data, needle->destination, needle->destination_len,

View File

@ -0,0 +1,14 @@
--- a/lib/http.c 2026-07-16 11:31:20.463436422 +0000
+++ b/lib/http.c 2026-07-16 11:31:28.407630431 +0000
@@ -675,8 +675,9 @@ output_auth_headers(struct Curl_easy *da
#ifndef CURL_DISABLE_BEARER_AUTH
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
- if((!proxy && data->set.str[STRING_BEARER] &&
- !Curl_checkheaders(data, STRCONST("Authorization")))) {
+ if(!proxy && data->set.str[STRING_BEARER] &&
+ Curl_auth_allowed_to_host(data) &&
+ !Curl_checkheaders(data, STRCONST("Authorization"))) {
auth = "Bearer";
result = http_output_bearer(data);
if(result)

View File

@ -0,0 +1,52 @@
--- a/lib/url.c 2026-07-16 11:31:47.953107760 +0000
+++ b/lib/url.c 2026-07-16 11:32:07.195577689 +0000
@@ -672,34 +672,19 @@ proxy_info_matches(const struct proxy_in
{
if((data->proxytype == needle->proxytype) &&
(data->port == needle->port) &&
- strcasecompare(data->host.name, needle->host.name))
+ strcasecompare(data->host.name, needle->host.name)) {
+
+ if(Curl_timestrcmp(data->user, needle->user) ||
+ Curl_timestrcmp(data->passwd, needle->passwd))
+ return FALSE;
return TRUE;
+ }
return FALSE;
}
-
-static bool
-socks_proxy_info_matches(const struct proxy_info *data,
- const struct proxy_info *needle)
-{
- if(!proxy_info_matches(data, needle))
- return FALSE;
-
- /* the user information is case-sensitive
- or at least it is not defined as case-insensitive
- see https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 */
-
- /* curl_strequal does a case insensitive comparison,
- so do not use it here! */
- if(Curl_timestrcmp(data->user, needle->user) ||
- Curl_timestrcmp(data->passwd, needle->passwd))
- return FALSE;
- return TRUE;
-}
#else
/* disabled, will not get called */
#define proxy_info_matches(x,y) FALSE
-#define socks_proxy_info_matches(x,y) FALSE
#endif
/* A connection has to have been idle for a shorter time than 'maxage_conn'
@@ -973,7 +958,7 @@ static bool url_match_conn(struct connec
return FALSE;
if(needle->bits.socksproxy &&
- !socks_proxy_info_matches(&needle->socks_proxy,
+ !proxy_info_matches(&needle->socks_proxy,
&conn->socks_proxy))
return FALSE;

View File

@ -0,0 +1,507 @@
From dbc1f8bc18be730add4400079f7a88457871cb48 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 18 May 2026 23:47:11 +0200
Subject: [PATCH 1/3] url: detect proxy changes read from environment
When a proxy is set from an environment variable, detect if that proxy
is not the same as previously and flush state.
Verified by test1647: verify changing proxy with env variables and make
sure Digest state is flushed in the second use
Closes #21666
---
lib/url.c | 11 ++++
lib/urldata.h | 1 +
tests/data/Makefile.am | 2 +
tests/data/test1647 | 103 +++++++++++++++++++++++++++++++
tests/libtest/Makefile.inc | 5 ++
tests/libtest/lib1647.c | 120 +++++++++++++++++++++++++++++++++++++
6 files changed, 242 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 dd5263f42..29fdd173a 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -335,6 +335,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
+ free(data->state.envproxy);
+#endif
free(data);
return CURLE_OK;
}
@@ -2533,6 +2536,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);
+ free(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/lib/urldata.h b/lib/urldata.h
index d9acb2b7b..0c22f2864 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1206,6 +1206,7 @@ struct UrlState {
void (*prev_signal)(int sig);
#endif
#ifndef CURL_DISABLE_DIGEST_AUTH
+ char *envproxy; /* last proxy string used for proxy-related state */
struct digestdata digest; /* state data for host Digest auth */
struct digestdata proxydigest; /* state data for proxy Digest auth */
#endif
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 01fbe9b23..601a7e7ac 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -218,6 +218,8 @@ test1620 test1621 \
\
test1630 test1631 test1632 test1633 test1634 test1635 \
\
+test1647 \
+\
test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \
test1660 test1661 test1662 test1663 test1664 \
\
diff --git a/tests/data/test1647 b/tests/data/test1647
new file mode 100644
index 000000000..a87487fa9
--- /dev/null
+++ b/tests/data/test1647
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+HTTP proxy Digest auth
+multi
+</keywords>
+</info>
+
+# Server-side
+<reply>
+
+# this is returned first since we get no proxy-auth
+<data crlf="headers" nocheck="yes">
+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.
+</data>
+
+# then this is returned when we get proxy-auth
+<data1000 crlf="headers">
+HTTP/1.1 200 OK
+Content-Length: 21
+Server: no
+
+Nice proxy auth sir!
+</data1000>
+
+<connect crlf="headers">
+HTTP/1.1 401 OK
+Content-Length: 21
+Server: no
+
+Denied access. Leave
+</connect>
+
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+https-proxy
+https
+</server>
+# tool is what to use instead of 'curl'
+<tool>
+lib%TESTNUMBER
+</tool>
+<features>
+!SSPI
+crypto
+proxy
+digest
+Debug
+</features>
+<setenv>
+http_proxy=%HOSTIP:%HTTPPORT
+https_proxy=https://%HOSTIP:%HTTPSPROXYPORT
+CURL_ENTROPY=99376
+</setenv>
+<name>
+HTTP proxy auth Digest, then change proxy with env var and do it again
+</name>
+<command>
+http://test.remote.example.com/path/%TESTNUMBER https://another.example.com:%HTTPSPORT/ daniel:monkey123 another:bump456
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="headers">
+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
+
+</protocol>
+
+<proxy crlf="headers">
+CONNECT another.example.com:%HTTPSPORT HTTP/1.1
+Host: another.example.com:%HTTPSPORT
+Proxy-Connection: Keep-Alive
+
+</proxy>
+
+# CONNECT fails
+<errorcode>
+7
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index cf4d6e712..fb3c3bb95 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -63,6 +63,8 @@ LIBTESTPROGS = libauthretry libntlmconnect libprereq \
lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 lib1568 lib1569 \
lib1591 lib1592 lib1593 lib1594 lib1596 lib1597 lib1598 \
\
+ lib1647 \
+ \
lib1662 \
\
lib1900 lib1901 \
@@ -545,6 +547,9 @@ lib1597_LDADD = $(TESTUTIL_LIBS)
lib1598_SOURCES = lib1598.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1598_LDADD = $(TESTUTIL_LIBS)
+lib1647_SOURCES = lib1647.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1647_LDADD = $(TESTUTIL_LIBS)
+
lib1662_SOURCES = lib1662.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1662_LDADD = $(TESTUTIL_LIBS)
diff --git a/tests/libtest/lib1647.c b/tests/libtest/lib1647.c
new file mode 100644
index 000000000..8060e1bfe
--- /dev/null
+++ b/tests/libtest/lib1647.c
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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;
+}
From 8bf120b21b871a250cfa506cc340a30befd268e9 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Wed, 29 Jul 2026 12:24:54 +0000
Subject: [PATCH 2/3] url: include vauth/vauth.h for Curl_auth_digest_cleanup
declaration
The upstream commit 5c225384b calls Curl_auth_digest_cleanup() in url.c,
but the function prototype is declared in vauth/vauth.h which was not
included in this version of url.c. The upstream url.c already included
this header before the fix was applied. Add the missing include to
fix compilation with -Werror=implicit-function-declaration.
---
lib/url.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/url.c b/lib/url.c
index 29fdd173a..19677e131 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -79,6 +79,7 @@
#include "share.h"
#include "content_encoding.h"
#include "http_digest.h"
+#include "vauth/vauth.h"
#include "http_negotiate.h"
#include "select.h"
#include "multiif.h"
From f4348a82622f56a78e7f109d1b1ae0e1abd80bba Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Wed, 29 Jul 2026 12:32:58 +0000
Subject: [PATCH 3/3] tests: adapt lib1647.c for 8.12.1 test infrastructure
- Use test.h instead of first.h (provides res_easy_setopt, res_global_init, etc.)
- Add testutil.h and warnless.h includes (needed for start_test_timing)
- Add memdebug.h include
- Change function signature from test_lib1647 to test (standard in this version)
- Use 'res' variable name instead of 'result' (required by test.h macros)
- Replace libtest_arg4 with test_argv[4] (arg4 not available in this version)
- Use fprintf(stderr, ...) instead of curl_mfprintf/curl_mprintf
---
tests/libtest/lib1647.c | 55 ++++++++++++++++++++++-------------------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/tests/libtest/lib1647.c b/tests/libtest/lib1647.c
index 8060e1bfe..d1e3ded8c 100644
--- a/tests/libtest/lib1647.c
+++ b/tests/libtest/lib1647.c
@@ -28,87 +28,90 @@
* argv4 = credentials 2
*/
-#include "first.h"
+#include "test.h"
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.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;
+ CURLcode res = CURLE_OK;
res_easy_setopt(curl, CURLOPT_URL, url);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
- if(result)
+ if(res)
goto init_failed;
res_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
- if(result)
+ if(res)
goto init_failed;
return CURLE_OK; /* success */
init_failed:
- return result; /* failure */
+ return res; /* failure */
}
static CURLcode run1647(CURL *curl, const char *url, const char *userpwd)
{
- CURLcode result = CURLE_OK;
+ CURLcode res = CURLE_OK;
- result = init1647(curl, url, userpwd);
- if(result)
- return result;
+ res = init1647(curl, url, userpwd);
+ if(res)
+ return res;
return curl_easy_perform(curl);
}
-static CURLcode test_lib1647(const char *URL)
+CURLcode test(char *URL)
{
- CURLcode result = CURLE_OK;
+ CURLcode res = CURLE_OK;
CURL *curl = NULL;
res_global_init(CURL_GLOBAL_ALL);
- if(result)
- return result;
+ if(res)
+ return res;
curl = curl_easy_init();
if(!curl) {
- curl_mfprintf(stderr, "curl_easy_init() failed\n");
+ fprintf(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)
+ fprintf(stderr, "--- First get '%s'\n", URL);
+ res = run1647(curl, URL, libtest_arg3);
+ if(res)
goto test_cleanup;
- curl_mprintf("--- Then get '%s'\n", libtest_arg2);
- result = run1647(curl, libtest_arg2, libtest_arg4);
+ fprintf(stderr, "--- Then get '%s'\n", libtest_arg2);
+ res = run1647(curl, libtest_arg2, test_argv[4]);
test_cleanup:
@@ -116,5 +119,5 @@ test_cleanup:
curl_easy_cleanup(curl);
curl_global_cleanup();
- return result;
+ return res;
}

View File

@ -1,7 +1,7 @@
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
Name: curl
Version: 8.12.1
Release: 4%{?dist}
Release: 4%{?dist}.4
License: curl
Source0: https://curl.se/download/%{name}-%{version}.tar.xz
Source1: https://curl.se/download/%{name}-%{version}.tar.xz.asc
@ -16,6 +16,30 @@ Patch001: 0001-curl-8.12.1-CVE-2025-9086.patch
# openssl: respect system crypto policy for TLS max version
Patch002: 0002-curl-8.12.1-respect-system-crypto-policy.patch
# openssl: toggling CURLSSLOPT_NO_PARTIALCHAIN makes a different CA cache (CVE-2025-14819)
Patch003: 0003-curl-8.12.1-CVE-2025-14819.patch
# vssh: fix SSH host key mismatch on type difference (CVE-2026-9547)
Patch004: 0004-curl-8.12.1-CVE-2026-9547.patch
# tool_operate: fix schemeless URL handling with --proto-default (CVE-2026-12064)
Patch005: 0005-curl-8.12.1-CVE-2026-12064.patch
# url: reject TLS-to-cleartext STARTTLS connection reuse (CVE-2026-8286)
Patch006: 0006-curl-8.12.1-CVE-2026-8286.patch
# url: fix reuse of connections using HTTP Negotiate (CVE-2026-1965)
Patch007: 0007-curl-8.12.1-CVE-2026-1965.patch
# http: only send bearer if auth is allowed (CVE-2026-3783)
Patch008: 0008-curl-8.12.1-CVE-2026-3783.patch
# proxy-auth: check proxy credentials on connection reuse (CVE-2026-3784)
Patch009: 0009-curl-8.12.1-CVE-2026-3784.patch
# url: detect proxy changes read from environment (CVE-2026-8927)
Patch010: 0010-curl-8.12.1-CVE-2026-8927.patch
# patch making libcurl multilib ready
Patch101: 0101-curl-7.32.0-multilib.patch
@ -401,6 +425,22 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
%{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
%changelog
* Wed Jul 29 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 8.12.1-4.4
- fix proxy environment variable change detection (CVE-2026-8927)
* Wed Jul 22 2026 Jacek Migacz <jmigacz@redhat.com> - 8.12.1-4.el10_2.3
- fix HTTP Negotiate connection reuse auth bypass (CVE-2026-1965)
- fix OAuth2 bearer token leak via redirect and netrc (CVE-2026-3783)
- fix proxy connection reuse with wrong credentials (CVE-2026-3784)
* Mon Jul 13 2026 Jacek Migacz <jmigacz@redhat.com> - 8.12.1-4.2
- fix SSH host key mismatch on type difference (CVE-2026-9547)
- fix schemeless URL handling with --proto-default (CVE-2026-12064)
- fix TLS/STARTTLS connection reuse vulnerability (CVE-2026-8286)
* Mon Apr 20 2026 Jacek Migacz <jmigacz@redhat.com> - 8.12.1-4.1
- openssl: fix CA cache reuse with CURLSSLOPT_NO_PARTIALCHAIN (CVE-2025-14819)
* Mon Nov 17 2025 Jacek Migacz <jmigacz@redhat.com> - 8.12.1-4
- openssl: respect system crypto policy for TLS max version (RHEL-128916)