public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/curl] f43: Resolves: CVE-2026-10536 - HTTP/2 stream-dependency tree UAF
@ 2026-09-09 8:10 Jan Macku
0 siblings, 0 replies; only message in thread
From: Jan Macku @ 2026-09-09 8:10 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/curl
Branch : f43
Commit : cf74472721f2707462c244097f1baecbc56c1205
Author : Jan Macku <jamacku@redhat.com>
Date : 2026-08-27T17:20:37+02:00
Stats : +352/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/curl/c/cf74472721f2707462c244097f1baecbc56c1205?branch=f43
Log:
Resolves: CVE-2026-10536 - HTTP/2 stream-dependency tree UAF
---
diff --git a/0019-curl-8.15.0-CVE-2026-10536.patch b/0019-curl-8.15.0-CVE-2026-10536.patch
new file mode 100644
index 0000000..bac657e
--- /dev/null
+++ b/0019-curl-8.15.0-CVE-2026-10536.patch
@@ -0,0 +1,345 @@
+From 14d00f9a97f60e34b0ed9d0a21dfab6df96ea468 Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <stefan@eissing.org>
+Date: Fri, 22 May 2026 09:11:41 +0200
+Subject: [PATCH] http2: remove stream dependency tracking
+
+The HTTP/2 feature is deprecated, few servers implement it and our
+implementation is complicated by its state management. Make the two
+CURLOPT_* involved a nop and deprecate them.
+
+Closes #21723
+
+(cherry picked from commit bfbff7852f050232edd3e5ca5c6bf2021c340f5a)
+---
+ docs/libcurl/curl_easy_setopt.md | 5 +-
+ docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md | 8 ++
+ docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md | 8 ++
+ docs/libcurl/symbols-in-versions | 4 +-
+ include/curl/curl.h | 6 +-
+ lib/http2.c | 18 ++--
+ lib/setopt.c | 9 +-
+ lib/url.c | 98 -------------------
+ lib/urldata.h | 8 --
+ 9 files changed, 34 insertions(+), 130 deletions(-)
+
+diff --git a/docs/libcurl/curl_easy_setopt.md b/docs/libcurl/curl_easy_setopt.md
+index ccca56de6b..4b06a8e0f6 100644
+--- a/docs/libcurl/curl_easy_setopt.md
++++ b/docs/libcurl/curl_easy_setopt.md
+@@ -1158,11 +1158,12 @@ Redirect stderr to another stream. See CURLOPT_STDERR(3)
+
+ ## CURLOPT_STREAM_DEPENDS
+
+-This HTTP/2 stream depends on another. See CURLOPT_STREAM_DEPENDS(3)
++**Deprecated option** This HTTP/2 stream depends on another. See
++CURLOPT_STREAM_DEPENDS(3)
+
+ ## CURLOPT_STREAM_DEPENDS_E
+
+-This HTTP/2 stream depends on another exclusively. See
++**Deprecated option** This HTTP/2 stream depends on another exclusively. See
+ CURLOPT_STREAM_DEPENDS_E(3)
+
+ ## CURLOPT_STREAM_WEIGHT
+diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
+index 5e3e177dce..e0e8ef0c53 100644
+--- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
++++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
+@@ -44,6 +44,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
+ a transfer that is about to be sent over the same HTTP/2 connection for this
+ option to have an actual effect.
+
++Since version 8.21.0 setting this option no longer has an effect. HTTP/2
++stream dependencies were introduced in RFC 7540 and then later deprecated
++in RFC 9113.
++
+ # DEFAULT
+
+ NULL
+@@ -69,6 +73,10 @@ int main(void)
+ }
+ ~~~
+
++# DEPRECATED
++
++Deprecated since 8.21.0.
++
+ # %AVAILABILITY%
+
+ # RETURN VALUE
+diff --git a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
+index fe95ae8d71..fe8f97f950 100644
+--- a/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
++++ b/docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
+@@ -47,6 +47,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
+ a transfer that is about to be sent over the same HTTP/2 connection for this
+ option to have an actual effect.
+
++Since version 8.21.0 setting this option no longer has an effect. HTTP/2
++stream dependencies were introduced in RFC 7540 and then later deprecated
++in RFC 9113.
++
+ # DEFAULT
+
+ NULL
+@@ -72,6 +76,10 @@ int main(void)
+ }
+ ~~~
+
++# DEPRECATED
++
++Deprecated since 8.21.0.
++
+ # %AVAILABILITY%
+
+ # RETURN VALUE
+diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
+index 4603dd322c..63e1414cc9 100644
+--- a/docs/libcurl/symbols-in-versions
++++ b/docs/libcurl/symbols-in-versions
+@@ -865,8 +865,8 @@ CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0
+ CURLOPT_SSLKEYTYPE 7.9.3
+ CURLOPT_SSLVERSION 7.1
+ CURLOPT_STDERR 7.1
+-CURLOPT_STREAM_DEPENDS 7.46.0
+-CURLOPT_STREAM_DEPENDS_E 7.46.0
++CURLOPT_STREAM_DEPENDS 7.46.0 8.21.0
++CURLOPT_STREAM_DEPENDS_E 7.46.0 8.21.0
+ CURLOPT_STREAM_WEIGHT 7.46.0
+ CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
+ CURLOPT_TCP_FASTOPEN 7.49.0
+diff --git a/include/curl/curl.h b/include/curl/curl.h
+index 7ef5b99349..6f74573f41 100644
+--- a/include/curl/curl.h
++++ b/include/curl/curl.h
+@@ -1976,10 +1976,12 @@ typedef enum {
+ CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
+
+ /* Set stream dependency on another curl handle */
+- CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
++ CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240,
++ 8.21.0, "Has no function"),
+
+ /* Set E-xclusive stream dependency on another curl handle */
+- CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
++ CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241,
++ 8.21.0, "Has no function"),
+
+ /* Do not send any tftp option requests to the server */
+ CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
+diff --git a/lib/http2.c b/lib/http2.c
+index 36dca426de..cb84d427b5 100644
+--- a/lib/http2.c
++++ b/lib/http2.c
+@@ -1931,16 +1931,12 @@ static int sweight_in_effect(const struct Curl_easy *data)
+ * struct.
+ */
+
+-static void h2_pri_spec(struct cf_h2_ctx *ctx,
+- struct Curl_easy *data,
++static void h2_pri_spec(struct Curl_easy *data,
+ nghttp2_priority_spec *pri_spec)
+ {
+ struct Curl_data_priority *prio = &data->set.priority;
+- struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
+- int32_t depstream_id = depstream ? depstream->id : 0;
+- nghttp2_priority_spec_init(pri_spec, depstream_id,
+- sweight_wanted(data),
+- data->set.priority.exclusive);
++ nghttp2_priority_spec_init(pri_spec, 0,
++ sweight_wanted(data), FALSE);
+ data->state.priority = *prio;
+ }
+
+@@ -1958,13 +1954,11 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
+ int rv = 0;
+
+ if(stream && stream->id > 0 &&
+- ((sweight_wanted(data) != sweight_in_effect(data)) ||
+- (data->set.priority.exclusive != data->state.priority.exclusive) ||
+- (data->set.priority.parent != data->state.priority.parent)) ) {
++ (sweight_wanted(data) != sweight_in_effect(data))) {
+ /* send new weight and/or dependency */
+ nghttp2_priority_spec pri_spec;
+
+- h2_pri_spec(ctx, data, &pri_spec);
++ h2_pri_spec(data, &pri_spec);
+ CURL_TRC_CF(data, cf, "[%d] Queuing PRIORITY", stream->id);
+ DEBUGASSERT(stream->id != -1);
+ rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE,
+@@ -2256,7 +2250,7 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
+ goto out;
+ }
+
+- h2_pri_spec(ctx, data, &pri_spec);
++ h2_pri_spec(data, &pri_spec);
+ if(!nghttp2_session_check_request_allowed(ctx->h2))
+ CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)");
+
+diff --git a/lib/setopt.c b/lib/setopt.c
+index 0ec31908a1..7d3c0a1a7b 100644
+--- a/lib/setopt.c
++++ b/lib/setopt.c
+@@ -1647,13 +1647,10 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option,
+
+ #ifdef USE_HTTP2
+ case CURLOPT_STREAM_DEPENDS:
+- case CURLOPT_STREAM_DEPENDS_E: {
+- struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
+- if(!dep || GOOD_EASY_HANDLE(dep))
+- return Curl_data_priority_add_child(dep, data,
+- option == CURLOPT_STREAM_DEPENDS_E);
++ case CURLOPT_STREAM_DEPENDS_E:
++ /* not doing stream dependencies any longer, but accept options
++ * for backward compatibility */
+ break;
+- }
+ #endif
+
+ default:
+diff --git a/lib/url.c b/lib/url.c
+index a652b82d36..6a429a1ce9 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -130,12 +130,6 @@
+ #include "curl_memory.h"
+ #include "memdebug.h"
+
+-#ifdef USE_NGHTTP2
+-static void data_priority_cleanup(struct Curl_easy *data);
+-#else
+-#define data_priority_cleanup(x)
+-#endif
+-
+ /* Some parts of the code (e.g. chunked encoding) assume this buffer has at
+ * more than just a few bytes to play with. Do not let it become too small or
+ * bad things will happen.
+@@ -302,8 +296,6 @@ CURLcode Curl_close(struct Curl_easy **datap)
+ Curl_resolv_unlink(data, &data->state.dns[0]); /* done with this */
+ Curl_resolv_unlink(data, &data->state.dns[1]);
+
+- data_priority_cleanup(data);
+-
+ /* No longer a dirty share, if it exists */
+ if(data->share) {
+ Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+@@ -4061,96 +4053,6 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
+
+ #if defined(USE_HTTP2) || defined(USE_HTTP3)
+
+-#ifdef USE_NGHTTP2
+-
+-static void priority_remove_child(struct Curl_easy *parent,
+- struct Curl_easy *child)
+-{
+- struct Curl_data_prio_node **pnext = &parent->set.priority.children;
+- struct Curl_data_prio_node *pnode = parent->set.priority.children;
+-
+- DEBUGASSERT(child->set.priority.parent == parent);
+- while(pnode && pnode->data != child) {
+- pnext = &pnode->next;
+- pnode = pnode->next;
+- }
+-
+- DEBUGASSERT(pnode);
+- if(pnode) {
+- *pnext = pnode->next;
+- free(pnode);
+- }
+-
+- child->set.priority.parent = 0;
+- child->set.priority.exclusive = FALSE;
+-}
+-
+-CURLcode Curl_data_priority_add_child(struct Curl_easy *parent,
+- struct Curl_easy *child,
+- bool exclusive)
+-{
+- if(child->set.priority.parent) {
+- priority_remove_child(child->set.priority.parent, child);
+- }
+-
+- if(parent) {
+- struct Curl_data_prio_node **tail;
+- struct Curl_data_prio_node *pnode;
+-
+- pnode = calloc(1, sizeof(*pnode));
+- if(!pnode)
+- return CURLE_OUT_OF_MEMORY;
+- pnode->data = child;
+-
+- if(parent->set.priority.children && exclusive) {
+- /* exclusive: move all existing children underneath the new child */
+- struct Curl_data_prio_node *node = parent->set.priority.children;
+- while(node) {
+- node->data->set.priority.parent = child;
+- node = node->next;
+- }
+-
+- tail = &child->set.priority.children;
+- while(*tail)
+- tail = &(*tail)->next;
+-
+- DEBUGASSERT(!*tail);
+- *tail = parent->set.priority.children;
+- parent->set.priority.children = 0;
+- }
+-
+- tail = &parent->set.priority.children;
+- while(*tail) {
+- (*tail)->data->set.priority.exclusive = FALSE;
+- tail = &(*tail)->next;
+- }
+-
+- DEBUGASSERT(!*tail);
+- *tail = pnode;
+- }
+-
+- child->set.priority.parent = parent;
+- child->set.priority.exclusive = exclusive;
+- return CURLE_OK;
+-}
+-
+-#endif /* USE_NGHTTP2 */
+-
+-#ifdef USE_NGHTTP2
+-static void data_priority_cleanup(struct Curl_easy *data)
+-{
+- while(data->set.priority.children) {
+- struct Curl_easy *tmp = data->set.priority.children->data;
+- priority_remove_child(data, tmp);
+- if(data->set.priority.parent)
+- Curl_data_priority_add_child(data->set.priority.parent, tmp, FALSE);
+- }
+-
+- if(data->set.priority.parent)
+- priority_remove_child(data->set.priority.parent, data);
+-}
+-#endif
+-
+ void Curl_data_priority_clear_state(struct Curl_easy *data)
+ {
+ memset(&data->state.priority, 0, sizeof(data->state.priority));
+diff --git a/lib/urldata.h b/lib/urldata.h
+index d24989f3c9..95f2efc55e 100644
+--- a/lib/urldata.h
++++ b/lib/urldata.h
+@@ -945,15 +945,7 @@ struct Curl_data_prio_node {
+ * on the same connection.
+ */
+ struct Curl_data_priority {
+-#ifdef USE_NGHTTP2
+- /* tree like dependencies only implemented in nghttp2 */
+- struct Curl_easy *parent;
+- struct Curl_data_prio_node *children;
+-#endif
+ int weight;
+-#ifdef USE_NGHTTP2
+- BIT(exclusive);
+-#endif
+ };
+
+ /* Timers */
+--
+2.55.0
+
diff --git a/curl.spec b/curl.spec
index 0441901..f1874b5 100644
--- a/curl.spec
+++ b/curl.spec
@@ -7,7 +7,7 @@
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
Name: curl
Version: 8.15.0
-Release: 9%{?dist}
+Release: 10%{?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
@@ -70,6 +70,9 @@ Patch017: 0017-curl-8.15.0-CVE-2026-9545.patch
# fix UAF after pause in socket callback (CVE-2026-9080)
Patch018: 0018-curl-8.15.0-CVE-2026-9080.patch
+# fix HTTP/2 stream-dependency tree UAF (CVE-2026-10536)
+Patch019: 0019-curl-8.15.0-CVE-2026-10536.patch
+
# patch making libcurl multilib ready
Patch101: 0101-curl-7.32.0-multilib.patch
@@ -472,6 +475,9 @@ rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/wcurl.1*
%{_libdir}/libcurl.so.4.[0-9].[0-9].minimal
%changelog
+* Tue Sep 08 2026 Jan Macku <jamacku@redhat.com> - 8.15.0-10
+- fix HTTP/2 stream-dependency tree UAF (CVE-2026-10536)
+
* Wed Aug 26 2026 Jan Macku <jamacku@redhat.com> - 8.15.0-9
- fix proto-default skips SSH verification (CVE-2026-12064)
- fix wrong STARTTLS connection reuse (CVE-2026-8286)
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-09 8:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09 8:10 [rpms/curl] f43: Resolves: CVE-2026-10536 - HTTP/2 stream-dependency tree UAF Jan Macku
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox