Skip to content

Commit bec0335

Browse files
[AutoPR- Security] Patch curl for CVE-2026-7168, CVE-2026-6276, CVE-2026-4873 [MEDIUM] (microsoft#17222)
Co-authored-by: jykanase <v-jykanase@microsoft.com>
1 parent ba6a157 commit bec0335

8 files changed

Lines changed: 781 additions & 15 deletions

File tree

SPECS/curl/CVE-2026-4873.patch

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
From 27418ff376aa27a2b57aa2c1cd2bdd0397836116 Mon Sep 17 00:00:00 2001
2+
From: Daniel Stenberg <daniel@haxx.se>
3+
Date: Tue, 24 Mar 2026 08:35:08 +0100
4+
Subject: [PATCH] url: do not reuse a non-tls starttls connection if new
5+
requires TLS
6+
7+
Reported-by: Arkadi Vainbrand
8+
9+
Closes #21082
10+
11+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
12+
Upstream-reference: https://github.com/curl/curl/commit/507e7be573b0a76fca597b75ff7cb27a66e7d865.patch
13+
---
14+
lib/url.c | 6 +++++-
15+
1 file changed, 5 insertions(+), 1 deletion(-)
16+
17+
diff --git a/lib/url.c b/lib/url.c
18+
index 88f559a..2ba5311 100644
19+
--- a/lib/url.c
20+
+++ b/lib/url.c
21+
@@ -841,7 +841,7 @@ struct url_conn_match {
22+
BIT(want_proxy_ntlm_http);
23+
BIT(want_nego_http);
24+
BIT(want_proxy_nego_http);
25+
-
26+
+ BIT(req_tls); /* require TLS use from a clear-text start */
27+
BIT(wait_pipe);
28+
BIT(force_reuse);
29+
BIT(seen_pending_conn);
30+
@@ -900,6 +900,9 @@ static bool url_match_auth_nego(struct connectdata *conn,
31+
}
32+
return FALSE; /* get another */
33+
}
34+
+ else if(m->req_tls)
35+
+ /* a clear-text STARTTLS protocol with required TLS */
36+
+ return FALSE;
37+
return TRUE;
38+
}
39+
#else
40+
@@ -1326,6 +1329,7 @@ ConnectionExists(struct Curl_easy *data,
41+
(needle->handler->protocol & PROTO_FAMILY_HTTP);
42+
#endif
43+
#endif
44+
+ match.req_tls = data->set.use_ssl >= CURLUSESSL_CONTROL;
45+
46+
/* Find a connection in the pool that matches what "data + needle"
47+
* requires. If a suitable candidate is found, it is attached to "data". */
48+
--
49+
2.45.4
50+

SPECS/curl/CVE-2026-6276.patch

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
From 3a19987a87f393d9394fe5acc7643f6c263c92db Mon Sep 17 00:00:00 2001
2+
From: Daniel Stenberg <daniel@haxx.se>
3+
Date: Tue, 14 Apr 2026 08:51:44 +0200
4+
Subject: [PATCH] urldata: move cookiehost to struct SingleRequest
5+
6+
To make it scoped for the single request appropriately.
7+
8+
Reported-by: Muhamad Arga Reksapati
9+
10+
Verify with libtest 2504: a custom Host *disabled* on reused handle
11+
12+
Closes #21312
13+
14+
Upstream Patch Reference: https://github.com/curl/curl/commit/3a19987a87f393d9394fe5acc7643f6c263c92db
15+
---
16+
lib/http.c | 14 +++---
17+
lib/request.c | 3 ++
18+
lib/request.h | 3 ++
19+
lib/url.c | 2 +-
20+
lib/urldata.h | 3 --
21+
tests/data/Makefile.am | 2 +-
22+
tests/data/test2504 | 52 +++++++++++++++++++++
23+
tests/libtest/Makefile.inc | 5 +-
24+
tests/libtest/lib2504.c | 93 ++++++++++++++++++++++++++++++++++++++
25+
9 files changed, 165 insertions(+), 12 deletions(-)
26+
create mode 100644 tests/data/test2504
27+
create mode 100644 tests/libtest/lib2504.c
28+
29+
diff --git a/lib/http.c b/lib/http.c
30+
index 4de1667..7d328e0 100644
31+
--- a/lib/http.c
32+
+++ b/lib/http.c
33+
@@ -1543,6 +1543,9 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
34+
data->state.first_remote_protocol = conn->handler->protocol;
35+
}
36+
Curl_safefree(aptr->host);
37+
+#ifndef CURL_DISABLE_COOKIES
38+
+ Curl_safefree(data->req.cookiehost);
39+
+#endif
40+
41+
ptr = Curl_checkheaders(data, STRCONST("Host"));
42+
if(ptr && (!data->state.this_is_a_follow ||
43+
@@ -1577,8 +1580,7 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
44+
if(colon)
45+
*colon = 0; /* The host must not include an embedded port number */
46+
}
47+
- Curl_safefree(aptr->cookiehost);
48+
- aptr->cookiehost = cookiehost;
49+
+ data->req.cookiehost = cookiehost;
50+
}
51+
#endif
52+
53+
@@ -2097,8 +2099,8 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
54+
int rc = 1;
55+
56+
if(data->cookies && data->state.cookie_engine) {
57+
- const char *host = data->state.aptr.cookiehost ?
58+
- data->state.aptr.cookiehost : conn->host.name;
59+
+ const char *host = data->req.cookiehost ?
60+
+ data->req.cookiehost : conn->host.name;
61+
const bool secure_context =
62+
conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
63+
strcasecompare("localhost", host) ||
64+
@@ -2920,8 +2922,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
65+
if(v) {
66+
/* If there is a custom-set Host: name, use it here, or else use
67+
* real peer hostname. */
68+
- const char *host = data->state.aptr.cookiehost ?
69+
- data->state.aptr.cookiehost : conn->host.name;
70+
+ const char *host = data->req.cookiehost ?
71+
+ data->req.cookiehost : conn->host.name;
72+
const bool secure_context =
73+
conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
74+
strcasecompare("localhost", host) ||
75+
diff --git a/lib/request.c b/lib/request.c
76+
index 310e4ea..088425d 100644
77+
--- a/lib/request.c
78+
+++ b/lib/request.c
79+
@@ -124,6 +124,9 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data)
80+
81+
#ifndef CURL_DISABLE_DOH
82+
Curl_doh_close(data);
83+
+#endif
84+
+#ifndef CURL_DISABLE_COOKIES
85+
+ Curl_safefree(req->cookiehost);
86+
#endif
87+
/* Can no longer memset() this struct as we need to keep some state */
88+
req->size = -1;
89+
diff --git a/lib/request.h b/lib/request.h
90+
index bb72247..90cb0ae 100644
91+
--- a/lib/request.h
92+
+++ b/lib/request.h
93+
@@ -119,6 +119,9 @@ struct SingleRequest {
94+
#ifndef CURL_DISABLE_DOH
95+
struct doh_probes *doh; /* DoH specific data for this request */
96+
#endif
97+
+#ifndef CURL_DISABLE_COOKIES
98+
+ char *cookiehost;
99+
+#endif
100+
#ifndef CURL_DISABLE_COOKIES
101+
unsigned char setcookies;
102+
#endif
103+
diff --git a/lib/url.c b/lib/url.c
104+
index 2ba5311..6ea7b30 100644
105+
--- a/lib/url.c
106+
+++ b/lib/url.c
107+
@@ -317,7 +317,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
108+
Curl_safefree(data->state.aptr.ref);
109+
Curl_safefree(data->state.aptr.host);
110+
#ifndef CURL_DISABLE_COOKIES
111+
- Curl_safefree(data->state.aptr.cookiehost);
112+
+ Curl_safefree(data->req.cookiehost);
113+
#endif
114+
#ifndef CURL_DISABLE_RTSP
115+
Curl_safefree(data->state.aptr.rtsp_transport);
116+
diff --git a/lib/urldata.h b/lib/urldata.h
117+
index 704fb7a..026fa2a 100644
118+
--- a/lib/urldata.h
119+
+++ b/lib/urldata.h
120+
@@ -1331,9 +1331,6 @@ struct UrlState {
121+
char *rangeline;
122+
char *ref;
123+
char *host;
124+
-#ifndef CURL_DISABLE_COOKIES
125+
- char *cookiehost;
126+
-#endif
127+
#ifndef CURL_DISABLE_RTSP
128+
char *rtsp_transport;
129+
#endif
130+
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
131+
index 26e015f..b0d1b0a 100644
132+
--- a/tests/data/Makefile.am
133+
+++ b/tests/data/Makefile.am
134+
@@ -259,7 +259,7 @@ test2308 test2309 \
135+
\
136+
test2400 test2401 test2402 test2403 test2404 test2405 test2406 \
137+
\
138+
-test2500 test2501 test2502 test2503 \
139+
+test2500 test2501 test2502 test2503 test2504 \
140+
\
141+
test2600 test2601 test2602 test2603 test2604 \
142+
\
143+
diff --git a/tests/data/test2504 b/tests/data/test2504
144+
new file mode 100644
145+
index 0000000..8cec1c8
146+
--- /dev/null
147+
+++ b/tests/data/test2504
148+
@@ -0,0 +1,52 @@
149+
+<?xml version="1.0" encoding="US-ASCII"?>
150+
+<testcase>
151+
+<info>
152+
+<keywords>
153+
+HTTP
154+
+cookies
155+
+</keywords>
156+
+</info>
157+
+
158+
+# Server-side
159+
+<reply>
160+
+<data crlf="headers" nocheck="yes">
161+
+HTTP/1.1 200 OK
162+
+Date: Tue, 09 Nov 2010 14:49:00 GMT
163+
+Server: server.example.com
164+
+Content-Length: 47
165+
+Set-Cookie: sid=SECRET123; Path=/
166+
+
167+
+file contents should appear once for each file
168+
+</data>
169+
+</reply>
170+
+
171+
+# Client-side
172+
+<client>
173+
+<server>
174+
+http
175+
+</server>
176+
+<tool>
177+
+lib%TESTNUMBER
178+
+</tool>
179+
+<name>
180+
+custom Host with cookie, handle reuse, no custom Host:
181+
+</name>
182+
+<command>
183+
+http://%HOSTIP:%HTTPPORT
184+
+</command>
185+
+</client>
186+
+
187+
+# Verify data after the test has been "shot"
188+
+<verify>
189+
+<protocol crlf="headers">
190+
+GET / HTTP/1.1
191+
+Host: victim.internal
192+
+Accept: */*
193+
+
194+
+GET / HTTP/1.1
195+
+Host: %HOSTIP:%HTTPPORT
196+
+Accept: */*
197+
+
198+
+</protocol>
199+
+</verify>
200+
+</testcase>
201+
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
202+
index 8f58fd6..b393665 100644
203+
--- a/tests/libtest/Makefile.inc
204+
+++ b/tests/libtest/Makefile.inc
205+
@@ -79,7 +79,7 @@ LIBTESTPROGS = libauthretry libntlmconnect libprereq \
206+
lib1970 lib1971 lib1972 lib1973 lib1974 lib1975 \
207+
lib2301 lib2302 lib2304 lib2305 lib2306 lib2308 lib2309 \
208+
lib2402 lib2404 lib2405 \
209+
- lib2502 \
210+
+ lib2502 lib2504 \
211+
lib3010 lib3025 lib3026 lib3027 \
212+
lib3100 lib3101 lib3102 lib3103 lib3207
213+
214+
@@ -698,6 +698,9 @@ lib2405_LDADD = $(TESTUTIL_LIBS)
215+
lib2502_SOURCES = lib2502.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) $(WARNLESS)
216+
lib2502_LDADD = $(TESTUTIL_LIBS)
217+
218+
+lib2504_SOURCES = lib2504.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE)
219+
+lib2504_LDADD = $(TESTUTIL_LIBS)
220+
+
221+
lib3010_SOURCES = lib3010.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
222+
lib3010_LDADD = $(TESTUTIL_LIBS)
223+
224+
diff --git a/tests/libtest/lib2504.c b/tests/libtest/lib2504.c
225+
new file mode 100644
226+
index 0000000..72b965d
227+
--- /dev/null
228+
+++ b/tests/libtest/lib2504.c
229+
@@ -0,0 +1,93 @@
230+
+/***************************************************************************
231+
+ * _ _ ____ _
232+
+ * Project ___| | | | _ \| |
233+
+ * / __| | | | |_) | |
234+
+ * | (__| |_| | _ <| |___
235+
+ * \___|\___/|_| \_\_____|
236+
+ *
237+
+ * Copyright (C) Linus Nielsen Feltzing <linus@haxx.se>
238+
+ *
239+
+ * This software is licensed as described in the file COPYING, which
240+
+ * you should have received as part of this distribution. The terms
241+
+ * are also available at https://curl.se/docs/copyright.html.
242+
+ *
243+
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
244+
+ * copies of the Software, and permit persons to whom the Software is
245+
+ * furnished to do so, under the terms of the COPYING file.
246+
+ *
247+
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
248+
+ * KIND, either express or implied.
249+
+ *
250+
+ * SPDX-License-Identifier: curl
251+
+ *
252+
+ ***************************************************************************/
253+
+#include "first.h"
254+
+
255+
+#include "testtrace.h"
256+
+
257+
+static size_t sink2504(char *ptr, size_t size, size_t nmemb, void *ud)
258+
+{
259+
+ (void)ptr;
260+
+ (void)ud;
261+
+ return size * nmemb;
262+
+}
263+
+
264+
+static void dump_cookies2504(CURL *h, const char *tag)
265+
+{
266+
+ struct curl_slist *cookies = NULL;
267+
+ struct curl_slist *nc;
268+
+ CURLcode rc = curl_easy_getinfo(h, CURLINFO_COOKIELIST, &cookies);
269+
+
270+
+ curl_mprintf("== %s ==\n", tag);
271+
+ if(rc) {
272+
+ curl_mprintf("getinfo error: %d\n", (int)rc);
273+
+ return;
274+
+ }
275+
+ for(nc = cookies; nc; nc = nc->next)
276+
+ puts(nc->data);
277+
+ curl_slist_free_all(cookies);
278+
+}
279+
+
280+
+static CURLcode test_lib2504(const char *URL)
281+
+{
282+
+ CURL *curl;
283+
+ CURLcode result = CURLE_OUT_OF_MEMORY;
284+
+ struct curl_slist *hdrs = NULL;
285+
+
286+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
287+
+ curl_mfprintf(stderr, "curl_global_init() failed\n");
288+
+ return TEST_ERR_MAJOR_BAD;
289+
+ }
290+
+
291+
+ curl = curl_easy_init();
292+
+ if(!curl) {
293+
+ curl_mfprintf(stderr, "curl_easy_init() failed\n");
294+
+ curl_global_cleanup();
295+
+ return TEST_ERR_MAJOR_BAD;
296+
+ }
297+
+
298+
+ hdrs = curl_slist_append(hdrs, "Host: victim.internal");
299+
+ if(hdrs) {
300+
+ test_setopt(curl, CURLOPT_WRITEFUNCTION, sink2504);
301+
+ test_setopt(curl, CURLOPT_COOKIEFILE, "");
302+
+ test_setopt(curl, CURLOPT_HTTPHEADER, hdrs);
303+
+ test_setopt(curl, CURLOPT_URL, URL);
304+
+
305+
+ result = curl_easy_perform(curl);
306+
+ curl_mprintf("req1=%d\n", (int)result);
307+
+ dump_cookies2504(curl, "after request 1");
308+
+
309+
+ test_setopt(curl, CURLOPT_HTTPHEADER, NULL);
310+
+ test_setopt(curl, CURLOPT_URL, URL);
311+
+
312+
+ result = curl_easy_perform(curl);
313+
+ curl_mprintf("req2=%d\n", (int)result);
314+
+ dump_cookies2504(curl, "after request 2");
315+
+ }
316+
+test_cleanup:
317+
+ curl_slist_free_all(hdrs);
318+
+ curl_easy_cleanup(curl);
319+
+ curl_global_cleanup();
320+
+
321+
+ return result;
322+
+}
323+
--
324+
2.45.4
325+

0 commit comments

Comments
 (0)