Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions SPECS/cmake/CVE-2026-4873.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 507e7be573b0a76fca597b75ff7cb27a66e7d865 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 24 Mar 2026 08:35:08 +0100
Subject: [PATCH] url: do not reuse a non-tls starttls connection if new
requires TLS

Reported-by: Arkadi Vainbrand

Closes #21082

Upstream Patch Reference: https://launchpadlibrarian.net/859770355/curl_8.5.0-2ubuntu10.8_8.5.0-2ubuntu10.9.diff.gz
https://github.com/curl/curl/commit/507e7be573b0a76fca597b75ff7cb27a66e7d865.patch
---
Utilities/cmcurl/lib/url.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 5f3eae4e..b8980f87 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -1188,6 +1188,11 @@ ConnectionExists(struct Curl_easy *data,
(get_protocol_family(check->handler) !=
needle->handler->protocol || !check->bits.tls_upgraded))
continue;
+ else if(!(needle->handler->flags & PROTOPT_SSL) &&
+ !check->bits.tls_upgraded &&
+ data->set.use_ssl >= CURLUSESSL_CONTROL)
+ /* do not reuse a non-TLS STARTTLS connection if TLS is required */
+ continue;

/* If needle has "conn_to_*" set, check must match this */
if((needle->bits.conn_to_host && !strcasecompare(
--
2.45.4

41 changes: 41 additions & 0 deletions SPECS/cmake/CVE-2026-5545.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
From 33e43985b8f3b9e66691d06e70be0395849856cd Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
Date: Thu, 2 Apr 2026 11:33:39 +0200
Subject: [PATCH] url: improve connection reuse on negotiate

Check state of negotiate to allow proper connection reuse.

Closes #21203

Upstream Patch Reference: https://launchpadlibrarian.net/859770355/curl_8.5.0-2ubuntu10.8_8.5.0-2ubuntu10.9.diff.gz
https://github.com/curl/curl/commit/33e43985b8f3b9e6669.patch
---
Utilities/cmcurl/lib/url.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 319ea1ea..47451df2 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -1228,9 +1228,16 @@ ConnectionExists(struct Curl_easy *data,
Curl_timestrcmp(needle->passwd, check->passwd)) {

/* we prefer a credential match, but this is at least a connection
- that can be reused and "upgraded" to NTLM */
- if(check->http_ntlm_state == NTLMSTATE_NONE)
+ that can be reused and "upgraded" to NTLM if it does
+ not have any auth ongoing. */
+#ifdef USE_SPNEGO
+ if((check->http_ntlm_state == NTLMSTATE_NONE)
+ && (check->http_negotiate_state == GSS_AUTHNONE)) {
+#else
+ if(check->http_ntlm_state == NTLMSTATE_NONE) {
+#endif
chosen = check;
+ }
continue;
}
}
--
2.45.4

222 changes: 222 additions & 0 deletions SPECS/cmake/CVE-2026-6253.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
From 188c2f166a20fa97c2325b2da7d0e5cecc13725f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 13 Apr 2026 17:17:23 +0200
Subject: [PATCH] http: clear the proxy credentials as well on port or scheme
change

Add tests 2009-2011 to verify switching between proxies with credentials
when the switch is driven by a redirect

Reported-by: Dwij Mehta

Upstream Patch Reference: https://launchpadlibrarian.net/859770351/curl_8.14.1-2ubuntu1.2_8.14.1-2ubuntu1.3.diff.gz
https://github.com/curl/curl/commit/188c2f166a20fa97c2325b2da7d0e5cecc13725f.patch
---
Utilities/cmcurl/lib/cf-h1-proxy.c | 25 ++++++------
Utilities/cmcurl/lib/cf-h2-proxy.c | 2 +-
Utilities/cmcurl/lib/transfer.c | 61 ++++++++++++++++++++++++------
Utilities/cmcurl/lib/transfer.h | 2 +
Utilities/cmcurl/lib/urldata.h | 5 +++
5 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/Utilities/cmcurl/lib/cf-h1-proxy.c b/Utilities/cmcurl/lib/cf-h1-proxy.c
index 093c33be..2d4a9e93 100644
--- a/Utilities/cmcurl/lib/cf-h1-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h1-proxy.c
@@ -419,17 +419,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,

if(ts->keepon == KEEPON_IGNORE) {
/* This means we are currently ignoring a response-body */
-
- if(ts->cl) {
- /* A Content-Length based body: simply count down the counter
- and make sure to break out of the loop when we're done! */
- ts->cl--;
- if(ts->cl <= 0) {
- ts->keepon = KEEPON_DONE;
- break;
- }
- }
- else if(ts->chunked_encoding) {
+ if(ts->chunked_encoding) {
/* chunked-encoded body, so we need to do the chunked dance
properly to know when the end of the body is reached */
size_t consumed = 0;
@@ -445,6 +435,15 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
ts->keepon = KEEPON_DONE;
}
}
+ else if(ts->cl) {
+ /* A Content-Length based body: count down the counter
+ and make sure to break out of the loop when we are done! */
+ ts->cl--;
+ if(ts->cl <= 0) {
+ ts->keepon = KEEPON_DONE;
+ break;
+ }
+ }
continue;
}

@@ -908,6 +907,8 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
/* read what is there */
CURL_TRC_CF(data, cf, "CONNECT receive");
result = recv_CONNECT_resp(cf, data, ts, &done);
+ if(result)
+ CURL_TRC_CF(data, cf, "error receiving CONNECT response: %d", result);
if(Curl_pgrsUpdate(data)) {
result = CURLE_ABORTED_BY_CALLBACK;
goto out;
@@ -961,7 +962,7 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
streamclose(conn, "proxy CONNECT failure");
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
- return CURLE_RECV_ERROR;
+ return CURLE_COULDNT_CONNECT;
}
/* 2xx response, SUCCESS! */
h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data);
diff --git a/Utilities/cmcurl/lib/cf-h2-proxy.c b/Utilities/cmcurl/lib/cf-h2-proxy.c
index 0bff15f3..d3cdbe80 100644
--- a/Utilities/cmcurl/lib/cf-h2-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h2-proxy.c
@@ -1016,7 +1016,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
}

/* Seems to have failed */
- return CURLE_RECV_ERROR;
+ return CURLE_COULDNT_CONNECT;
}

static CURLcode H2_CONNECT(struct Curl_cfilter *cf,
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index 744227eb..15aa9d29 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -559,6 +559,40 @@ void Curl_init_CONNECT(struct Curl_easy *data)
data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
}

+/*
+ * Restore the user credentials to those set in options.
+ */
+CURLcode Curl_reset_userpwd(struct Curl_easy *data)
+{
+ CURLcode result;
+ if(data->set.str[STRING_USERNAME] || data->set.str[STRING_PASSWORD])
+ data->state.creds_from = CREDS_OPTION;
+ result = Curl_setstropt(&data->state.aptr.user,
+ data->set.str[STRING_USERNAME]);
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.passwd,
+ data->set.str[STRING_PASSWORD]);
+ return result;
+}
+
+/*
+ * Restore the proxy credentials to those set in options.
+ */
+CURLcode Curl_reset_proxypwd(struct Curl_easy *data)
+{
+#ifndef CURL_DISABLE_PROXY
+ CURLcode result = Curl_setstropt(&data->state.aptr.proxyuser,
+ data->set.str[STRING_PROXYUSERNAME]);
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.proxypasswd,
+ data->set.str[STRING_PROXYPASSWORD]);
+ return result;
+#else
+ (void)data;
+ return CURLE_OK;
+#endif
+}
+
/*
* Curl_pretransfer() is called immediately before a transfer starts, and only
* once for one transfer no matter if it has redirects or do multi-pass
@@ -707,19 +741,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
}

if(!result)
- result = Curl_setstropt(&data->state.aptr.user,
- data->set.str[STRING_USERNAME]);
- if(!result)
- result = Curl_setstropt(&data->state.aptr.passwd,
- data->set.str[STRING_PASSWORD]);
-#ifndef CURL_DISABLE_PROXY
- if(!result)
- result = Curl_setstropt(&data->state.aptr.proxyuser,
- data->set.str[STRING_PROXYUSERNAME]);
+ result = Curl_reset_userpwd(data);
if(!result)
- result = Curl_setstropt(&data->state.aptr.proxypasswd,
- data->set.str[STRING_PROXYPASSWORD]);
-#endif
+ result = Curl_reset_proxypwd(data);

data->req.headerbytecount = 0;
Curl_headers_cleanup(data);
@@ -894,11 +918,24 @@ CURLcode Curl_follow(struct Curl_easy *data,
free(scheme);
}
if(clear) {
+ CURLcode result = Curl_reset_userpwd(data);
+ if(result) {
+ free(newurl);
+ return result;
+ }
Curl_safefree(data->state.aptr.user);
Curl_safefree(data->state.aptr.passwd);
}
}
}
+ DEBUGASSERT(newurl);
+ {
+ CURLcode result = Curl_reset_proxypwd(data);
+ if(result) {
+ free(newurl);
+ return result;
+ }
+ }

if(type == FOLLOW_FAKE) {
/* we're only figuring out the new url if we would've followed locations
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
index ad0f3a20..7a1dc174 100644
--- a/Utilities/cmcurl/lib/transfer.h
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -31,6 +31,8 @@ char *Curl_checkheaders(const struct Curl_easy *data,

void Curl_init_CONNECT(struct Curl_easy *data);

+CURLcode Curl_reset_userpwd(struct Curl_easy *data);
+CURLcode Curl_reset_proxypwd(struct Curl_easy *data);
CURLcode Curl_pretransfer(struct Curl_easy *data);
CURLcode Curl_posttransfer(struct Curl_easy *data);

diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index fffac9f5..95ce93f7 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -1222,6 +1222,8 @@ struct urlpieces {
char *query;
};

+#define CREDS_OPTION 2 /* set with a CURLOPT_ */
+
struct UrlState {
/* Points to the connection cache */
struct conncache *conn_cache;
@@ -1372,6 +1374,9 @@ struct UrlState {
unsigned char select_bits; /* != 0 -> bitmask of socket events for this
transfer overriding anything the socket may
report */
+ unsigned int creds_from:2; /* where is the server credentials originating
+ from, see the CREDS_* defines above */
+
#ifdef CURLDEBUG
BIT(conncache_lock);
#endif
--
2.45.4

Loading
Loading