Skip to content

Commit ca1b8f4

Browse files
CBL-Mariner-Botazurelinux-securityAkarshHCL
authored
Merge PR "[AUTO-CHERRYPICK] [AutoPR- Security] Patch curl for CVE-2026-8932, CVE-2026-8927, CVE-2026-8926, CVE-2026-12064, CVE-2026-8458, CVE-2026-9079, CVE-2026-8286, CVE-2026-10536 [CRITICAL] - branch 3.0-dev" #17991
Co-authored-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> Co-authored-by: Akarsh Chaudhary <v-akarshc@microsoft.com>
1 parent f4688f2 commit ca1b8f4

13 files changed

Lines changed: 2094 additions & 15 deletions

SPECS/curl/CVE-2026-10536.patch

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
From 58384112815014d94d5b35ddbe4b96b033224b81 Mon Sep 17 00:00:00 2001
2+
From: AllSpark <allspark@microsoft.com>
3+
Date: Wed, 8 Jul 2026 11:01:50 +0000
4+
Subject: [PATCH] http2: remove stream dependency tracking
5+
6+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
7+
Upstream-reference: AI Backport of https://github.com/curl/curl/commit/bfbff7852f050232edd3e5ca.patch
8+
---
9+
docs/libcurl/curl_easy_setopt.md | 5 +-
10+
docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md | 8 ++
11+
docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md | 8 ++
12+
docs/libcurl/symbols-in-versions | 4 +-
13+
include/curl/curl.h | 6 +-
14+
lib/http2.c | 18 ++---
15+
lib/setopt.c | 9 +-
16+
lib/url.c | 96 -------------------------
17+
lib/urldata.h | 8 --
18+
9 files changed, 34 insertions(+), 128 deletions(-)
19+
20+
diff --git a/docs/libcurl/curl_easy_setopt.md b/docs/libcurl/curl_easy_setopt.md
21+
index e0fe95c..73e240d 100644
22+
--- a/docs/libcurl/curl_easy_setopt.md
23+
+++ b/docs/libcurl/curl_easy_setopt.md
24+
@@ -1146,11 +1146,12 @@ Redirect stderr to another stream. See CURLOPT_STDERR(3)
25+
26+
## CURLOPT_STREAM_DEPENDS
27+
28+
-This HTTP/2 stream depends on another. See CURLOPT_STREAM_DEPENDS(3)
29+
+**Deprecated option** This HTTP/2 stream depends on another. See
30+
+CURLOPT_STREAM_DEPENDS(3)
31+
32+
## CURLOPT_STREAM_DEPENDS_E
33+
34+
-This HTTP/2 stream depends on another exclusively. See
35+
+**Deprecated option** This HTTP/2 stream depends on another exclusively. See
36+
CURLOPT_STREAM_DEPENDS_E(3)
37+
38+
## CURLOPT_STREAM_WEIGHT
39+
diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
40+
index 1429de1..4fc90b8 100644
41+
--- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
42+
+++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
43+
@@ -44,6 +44,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
44+
a transfer that is about to be sent over the same HTTP/2 connection for this
45+
option to have an actual effect.
46+
47+
+Since version 8.21.0 setting this option no longer has an effect. HTTP/2
48+
+stream dependencies were introduced in RFC 7540 and then later deprecated
49+
+in RFC 9113.
50+
+
51+
# DEFAULT
52+
53+
NULL
54+
@@ -69,6 +73,10 @@ int main(void)
55+
}
56+
~~~
57+
58+
+# DEPRECATED
59+
+
60+
+Deprecated since 8.21.0.
61+
+
62+
# %AVAILABILITY%
63+
64+
# RETURN VALUE
65+
diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
66+
index bddfead..0e85b72 100644
67+
--- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
68+
+++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
69+
@@ -47,6 +47,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
70+
a transfer that is about to be sent over the same HTTP/2 connection for this
71+
option to have an actual effect.
72+
73+
+Since version 8.21.0 setting this option no longer has an effect. HTTP/2
74+
+stream dependencies were introduced in RFC 7540 and then later deprecated
75+
+in RFC 9113.
76+
+
77+
# DEFAULT
78+
79+
NULL
80+
@@ -72,6 +76,10 @@ int main(void)
81+
}
82+
~~~
83+
84+
+# DEPRECATED
85+
+
86+
+Deprecated since 8.21.0.
87+
+
88+
# %AVAILABILITY%
89+
90+
# RETURN VALUE
91+
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
92+
index ddda26d..b56527b 100644
93+
--- a/docs/libcurl/symbols-in-versions
94+
+++ b/docs/libcurl/symbols-in-versions
95+
@@ -858,8 +858,8 @@ CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0
96+
CURLOPT_SSLKEYTYPE 7.9.3
97+
CURLOPT_SSLVERSION 7.1
98+
CURLOPT_STDERR 7.1
99+
-CURLOPT_STREAM_DEPENDS 7.46.0
100+
-CURLOPT_STREAM_DEPENDS_E 7.46.0
101+
+CURLOPT_STREAM_DEPENDS 7.46.0 8.21.0
102+
+CURLOPT_STREAM_DEPENDS_E 7.46.0 8.21.0
103+
CURLOPT_STREAM_WEIGHT 7.46.0
104+
CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
105+
CURLOPT_TCP_FASTOPEN 7.49.0
106+
diff --git a/include/curl/curl.h b/include/curl/curl.h
107+
index 1883558..8e04952 100644
108+
--- a/include/curl/curl.h
109+
+++ b/include/curl/curl.h
110+
@@ -1960,10 +1960,12 @@ typedef enum {
111+
CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
112+
113+
/* Set stream dependency on another CURL handle */
114+
- CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
115+
+ CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240,
116+
+ 8.21.0, "Has no function"),
117+
118+
/* Set E-xclusive stream dependency on another CURL handle */
119+
- CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
120+
+ CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241,
121+
+ 8.21.0, "Has no function"),
122+
123+
/* Do not send any tftp option requests to the server */
124+
CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
125+
diff --git a/lib/http2.c b/lib/http2.c
126+
index ef29686..2871c3d 100644
127+
--- a/lib/http2.c
128+
+++ b/lib/http2.c
129+
@@ -1872,16 +1872,12 @@ static int sweight_in_effect(const struct Curl_easy *data)
130+
* struct.
131+
*/
132+
133+
-static void h2_pri_spec(struct cf_h2_ctx *ctx,
134+
- struct Curl_easy *data,
135+
+static void h2_pri_spec(struct Curl_easy *data,
136+
nghttp2_priority_spec *pri_spec)
137+
{
138+
struct Curl_data_priority *prio = &data->set.priority;
139+
- struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
140+
- int32_t depstream_id = depstream ? depstream->id : 0;
141+
- nghttp2_priority_spec_init(pri_spec, depstream_id,
142+
- sweight_wanted(data),
143+
- data->set.priority.exclusive);
144+
+ nghttp2_priority_spec_init(pri_spec, 0,
145+
+ sweight_wanted(data), FALSE);
146+
data->state.priority = *prio;
147+
}
148+
149+
@@ -1899,13 +1895,11 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
150+
int rv = 0;
151+
152+
if(stream && stream->id > 0 &&
153+
- ((sweight_wanted(data) != sweight_in_effect(data)) ||
154+
- (data->set.priority.exclusive != data->state.priority.exclusive) ||
155+
- (data->set.priority.parent != data->state.priority.parent)) ) {
156+
+ (sweight_wanted(data) != sweight_in_effect(data))) {
157+
/* send new weight and/or dependency */
158+
nghttp2_priority_spec pri_spec;
159+
160+
- h2_pri_spec(ctx, data, &pri_spec);
161+
+ h2_pri_spec(data, &pri_spec);
162+
CURL_TRC_CF(data, cf, "[%d] Queuing PRIORITY", stream->id);
163+
DEBUGASSERT(stream->id != -1);
164+
rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE,
165+
@@ -2210,7 +2205,7 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream,
166+
goto out;
167+
}
168+
169+
- h2_pri_spec(ctx, data, &pri_spec);
170+
+ h2_pri_spec(data, &pri_spec);
171+
if(!nghttp2_session_check_request_allowed(ctx->h2))
172+
CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)");
173+
174+
diff --git a/lib/setopt.c b/lib/setopt.c
175+
index 1ab0d1e..6b8cbb3 100644
176+
--- a/lib/setopt.c
177+
+++ b/lib/setopt.c
178+
@@ -1652,13 +1652,10 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option,
179+
180+
#ifdef USE_HTTP2
181+
case CURLOPT_STREAM_DEPENDS:
182+
- case CURLOPT_STREAM_DEPENDS_E: {
183+
- struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
184+
- if(!dep || GOOD_EASY_HANDLE(dep))
185+
- return Curl_data_priority_add_child(dep, data,
186+
- option == CURLOPT_STREAM_DEPENDS_E);
187+
+ case CURLOPT_STREAM_DEPENDS_E:
188+
+ /* not doing stream dependencies any longer, but accept options
189+
+ * for backward compatibility */
190+
break;
191+
- }
192+
#endif
193+
194+
default:
195+
diff --git a/lib/url.c b/lib/url.c
196+
index cd8dbcc..7923485 100644
197+
--- a/lib/url.c
198+
+++ b/lib/url.c
199+
@@ -130,12 +130,6 @@
200+
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
201+
#endif
202+
203+
-#ifdef USE_NGHTTP2
204+
-static void data_priority_cleanup(struct Curl_easy *data);
205+
-#else
206+
-#define data_priority_cleanup(x)
207+
-#endif
208+
-
209+
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
210+
* more than just a few bytes to play with. Do not let it become too small or
211+
* bad things will happen.
212+
@@ -298,7 +292,6 @@ CURLcode Curl_close(struct Curl_easy **datap)
213+
Curl_resolver_cancel(data);
214+
Curl_resolver_cleanup(data->state.async.resolver);
215+
216+
- data_priority_cleanup(data);
217+
218+
/* No longer a dirty share, if it exists */
219+
if(data->share) {
220+
@@ -3957,96 +3949,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
221+
222+
#if defined(USE_HTTP2) || defined(USE_HTTP3)
223+
224+
-#ifdef USE_NGHTTP2
225+
-
226+
-static void priority_remove_child(struct Curl_easy *parent,
227+
- struct Curl_easy *child)
228+
-{
229+
- struct Curl_data_prio_node **pnext = &parent->set.priority.children;
230+
- struct Curl_data_prio_node *pnode = parent->set.priority.children;
231+
-
232+
- DEBUGASSERT(child->set.priority.parent == parent);
233+
- while(pnode && pnode->data != child) {
234+
- pnext = &pnode->next;
235+
- pnode = pnode->next;
236+
- }
237+
-
238+
- DEBUGASSERT(pnode);
239+
- if(pnode) {
240+
- *pnext = pnode->next;
241+
- free(pnode);
242+
- }
243+
-
244+
- child->set.priority.parent = 0;
245+
- child->set.priority.exclusive = FALSE;
246+
-}
247+
-
248+
-CURLcode Curl_data_priority_add_child(struct Curl_easy *parent,
249+
- struct Curl_easy *child,
250+
- bool exclusive)
251+
-{
252+
- if(child->set.priority.parent) {
253+
- priority_remove_child(child->set.priority.parent, child);
254+
- }
255+
-
256+
- if(parent) {
257+
- struct Curl_data_prio_node **tail;
258+
- struct Curl_data_prio_node *pnode;
259+
-
260+
- pnode = calloc(1, sizeof(*pnode));
261+
- if(!pnode)
262+
- return CURLE_OUT_OF_MEMORY;
263+
- pnode->data = child;
264+
-
265+
- if(parent->set.priority.children && exclusive) {
266+
- /* exclusive: move all existing children underneath the new child */
267+
- struct Curl_data_prio_node *node = parent->set.priority.children;
268+
- while(node) {
269+
- node->data->set.priority.parent = child;
270+
- node = node->next;
271+
- }
272+
-
273+
- tail = &child->set.priority.children;
274+
- while(*tail)
275+
- tail = &(*tail)->next;
276+
-
277+
- DEBUGASSERT(!*tail);
278+
- *tail = parent->set.priority.children;
279+
- parent->set.priority.children = 0;
280+
- }
281+
-
282+
- tail = &parent->set.priority.children;
283+
- while(*tail) {
284+
- (*tail)->data->set.priority.exclusive = FALSE;
285+
- tail = &(*tail)->next;
286+
- }
287+
-
288+
- DEBUGASSERT(!*tail);
289+
- *tail = pnode;
290+
- }
291+
-
292+
- child->set.priority.parent = parent;
293+
- child->set.priority.exclusive = exclusive;
294+
- return CURLE_OK;
295+
-}
296+
-
297+
-#endif /* USE_NGHTTP2 */
298+
-
299+
-#ifdef USE_NGHTTP2
300+
-static void data_priority_cleanup(struct Curl_easy *data)
301+
-{
302+
- while(data->set.priority.children) {
303+
- struct Curl_easy *tmp = data->set.priority.children->data;
304+
- priority_remove_child(data, tmp);
305+
- if(data->set.priority.parent)
306+
- Curl_data_priority_add_child(data->set.priority.parent, tmp, FALSE);
307+
- }
308+
-
309+
- if(data->set.priority.parent)
310+
- priority_remove_child(data->set.priority.parent, data);
311+
-}
312+
-#endif
313+
314+
void Curl_data_priority_clear_state(struct Curl_easy *data)
315+
{
316+
memset(&data->state.priority, 0, sizeof(data->state.priority));
317+
diff --git a/lib/urldata.h b/lib/urldata.h
318+
index 9d4c33a..f12958d 100644
319+
--- a/lib/urldata.h
320+
+++ b/lib/urldata.h
321+
@@ -1145,15 +1145,7 @@ struct Curl_data_prio_node {
322+
* TODO: we need to adapt it to the new priority scheme as defined in RFC 9218
323+
*/
324+
struct Curl_data_priority {
325+
-#ifdef USE_NGHTTP2
326+
- /* tree like dependencies only implemented in nghttp2 */
327+
- struct Curl_easy *parent;
328+
- struct Curl_data_prio_node *children;
329+
-#endif
330+
int weight;
331+
-#ifdef USE_NGHTTP2
332+
- BIT(exclusive);
333+
-#endif
334+
};
335+
336+
/* Timers */
337+
--
338+
2.45.4
339+

0 commit comments

Comments
 (0)