aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/patches
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-10-11 21:07:18 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-10-11 21:17:24 +0300
commit1df197e6035ea9826bfedee7d48812e318ba9c7a (patch)
tree76b8e9de41820755adf209854d06a84a8b5a1988 /contrib/libs/curl/patches
parentf9c007ea1b59b960201def74990810b26ecdfd48 (diff)
downloadydb-1df197e6035ea9826bfedee7d48812e318ba9c7a.tar.gz
Revert "Update contrib/libs/curl to 8.10.1" to fix
Revert "Update contrib/libs/curl to 8.10.1" This reverts commit 428ef806a15515cdaa325530aa8cc6903fac5fb6, reversing changes made to 40e46e6394df409d1545a3771c8a47a86ed55eac. Revert "Fix formatting after rXXXXXX" This reverts commit a73689311a92e195d14136c5a0049ef1e40b1f3e, reversing changes made to 17980b8756d1f74d3dacddc7ca4945c30f35611c. commit_hash:5c5194831e5455b61fbee61619066396626beab1
Diffstat (limited to 'contrib/libs/curl/patches')
-rw-r--r--contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch120
-rw-r--r--contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch74
2 files changed, 194 insertions, 0 deletions
diff --git a/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch b/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch
new file mode 100644
index 0000000000..e60c53fff2
--- /dev/null
+++ b/contrib/libs/curl/patches/pr12562-nghttp2-segfault-fix.patch
@@ -0,0 +1,120 @@
+From 35380273b9311cf0741e386284310fa7ca4d005e Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <stefan@eissing.org>
+Date: Tue, 19 Dec 2023 12:57:40 +0100
+Subject: [PATCH] http2: improved on_stream_close/data_done handling
+
+- there seems to be a code path that cleans up easy handles without
+ triggering DONE or DETACH events to the connection filters. This
+ would explain wh nghttp2 still holds stream user data
+- add GOOD check to easy handle used in on_close_callback to
+ prevent crashes, ASSERTs in debug builds.
+- NULL the stream user data early before submitting RST
+- add checks in on_stream_close() to identify UNGOOD easy handles
+
+Reported-by: Hans-Christian Egtvedt
+Fixes #10936
+Closes #12562
+---
+ lib/http2.c | 50 ++++++++++++++++++++++++------------
+ tests/http/test_07_upload.py | 17 ++++++++++++
+ tests/http/testenv/curl.py | 2 +-
+ 3 files changed, 51 insertions(+), 18 deletions(-)
+
+diff --git a/lib/http2.c b/lib/http2.c
+index 59903cfa72d250..dcc24ea102302c 100644
+--- a/lib/http2.c
++++ b/lib/http2.c
+@@ -283,13 +283,20 @@ static void http2_data_done(struct Curl_cfilter *cf,
+ return;
+
+ if(ctx->h2) {
++ bool flush_egress = FALSE;
++ /* returns error if stream not known, which is fine here */
++ (void)nghttp2_session_set_stream_user_data(ctx->h2, stream->id, NULL);
++
+ if(!stream->closed && stream->id > 0) {
+ /* RST_STREAM */
+ CURL_TRC_CF(data, cf, "[%d] premature DATA_DONE, RST stream",
+ stream->id);
+- if(!nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE,
+- stream->id, NGHTTP2_STREAM_CLOSED))
+- (void)nghttp2_session_send(ctx->h2);
++ stream->closed = TRUE;
++ stream->reset = TRUE;
++ stream->send_closed = TRUE;
++ nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE,
++ stream->id, NGHTTP2_STREAM_CLOSED);
++ flush_egress = TRUE;
+ }
+ if(!Curl_bufq_is_empty(&stream->recvbuf)) {
+ /* Anything in the recvbuf is still being counted
+@@ -299,19 +306,11 @@ static void http2_data_done(struct Curl_cfilter *cf,
+ nghttp2_session_consume(ctx->h2, stream->id,
+ Curl_bufq_len(&stream->recvbuf));
+ /* give WINDOW_UPATE a chance to be sent, but ignore any error */
+- (void)h2_progress_egress(cf, data);
++ flush_egress = TRUE;
+ }
+
+- /* -1 means unassigned and 0 means cleared */
+- if(nghttp2_session_get_stream_user_data(ctx->h2, stream->id)) {
+- int rv = nghttp2_session_set_stream_user_data(ctx->h2,
+- stream->id, 0);
+- if(rv) {
+- infof(data, "http/2: failed to clear user_data for stream %u",
+- stream->id);
+- DEBUGASSERT(0);
+- }
+- }
++ if(flush_egress)
++ nghttp2_session_send(ctx->h2);
+ }
+
+ Curl_bufq_free(&stream->sendbuf);
+@@ -1316,26 +1315,43 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
+ uint32_t error_code, void *userp)
+ {
+ struct Curl_cfilter *cf = userp;
+- struct Curl_easy *data_s;
++ struct Curl_easy *data_s, *call_data = CF_DATA_CURRENT(cf);
+ struct stream_ctx *stream;
+ int rv;
+ (void)session;
+
++ DEBUGASSERT(call_data);
+ /* get the stream from the hash based on Stream ID, stream ID zero is for
+ connection-oriented stuff */
+ data_s = stream_id?
+ nghttp2_session_get_stream_user_data(session, stream_id) : NULL;
+ if(!data_s) {
++ CURL_TRC_CF(call_data, cf,
++ "[%d] on_stream_close, no easy set on stream", stream_id);
+ return 0;
+ }
++ if(!GOOD_EASY_HANDLE(data_s)) {
++ /* nghttp2 still has an easy registered for the stream which has
++ * been freed be libcurl. This points to a code path that does not
++ * trigger DONE or DETACH events as it must. */
++ CURL_TRC_CF(call_data, cf,
++ "[%d] on_stream_close, not a GOOD easy on stream", stream_id);
++ (void)nghttp2_session_set_stream_user_data(session, stream_id, 0);
++ return NGHTTP2_ERR_CALLBACK_FAILURE;
++ }
+ stream = H2_STREAM_CTX(data_s);
+- if(!stream)
++ if(!stream) {
++ CURL_TRC_CF(data_s, cf,
++ "[%d] on_stream_close, GOOD easy but no stream", stream_id);
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
++ }
+
+ stream->closed = TRUE;
+ stream->error = error_code;
+- if(stream->error)
++ if(stream->error) {
+ stream->reset = TRUE;
++ stream->send_closed = TRUE;
++ }
+
+ if(stream->error)
+ CURL_TRC_CF(data_s, cf, "[%d] RESET: %s (err %d)",
diff --git a/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch b/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch
new file mode 100644
index 0000000000..a57512b2a2
--- /dev/null
+++ b/contrib/libs/curl/patches/pr12633-fix-mpd-streaming.patch
@@ -0,0 +1,74 @@
+From 3a24ef09af5fe7fdd672dee72ff760f871105a03 Mon Sep 17 00:00:00 2001
+From: Stefan Eissing <stefan@eissing.org>
+Date: Thu, 4 Jan 2024 10:06:17 +0100
+Subject: [PATCH] adjust_pollset fix
+
+- do not add a socket for POLLIN when the transfer does not
+ want to send (for example is paused).
+- refs #12632
+---
+ lib/cf-socket.c | 2 +-
+ lib/http2.c | 4 ++--
+ lib/vquic/curl_ngtcp2.c | 7 ++++---
+ lib/vquic/curl_quiche.c | 2 +-
+ 4 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/lib/cf-socket.c b/lib/cf-socket.c
+index bd4f0d1e97e2d3..c86aa7e7c2a969 100644
+--- a/lib/cf-socket.c
++++ b/lib/cf-socket.c
+@@ -1243,7 +1243,7 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf,
+ if(ctx->sock != CURL_SOCKET_BAD) {
+ if(!cf->connected)
+ Curl_pollset_set_out_only(data, ps, ctx->sock);
+- else
++ else if(CURL_WANT_RECV(data))
+ Curl_pollset_add_in(data, ps, ctx->sock);
+ CURL_TRC_CF(data, cf, "adjust_pollset -> %d socks", ps->num);
+ }
+diff --git a/lib/http2.c b/lib/http2.c
+index dcc24ea102302c..b7a08607945357 100644
+--- a/lib/http2.c
++++ b/lib/http2.c
+@@ -2341,8 +2341,8 @@ static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
+ bool c_exhaust, s_exhaust;
+
+ CF_DATA_SAVE(save, cf, data);
+- c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2);
+- s_exhaust = stream && stream->id >= 0 &&
++ c_exhaust = want_send && !nghttp2_session_get_remote_window_size(ctx->h2);
++ s_exhaust = want_send && stream && stream->id >= 0 &&
+ !nghttp2_session_get_stream_remote_window_size(ctx->h2,
+ stream->id);
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c
+index f4edf2d636ef93..89f690462d640b 100644
+--- a/lib/vquic/curl_ngtcp2.c
++++ b/lib/vquic/curl_ngtcp2.c
+@@ -1166,9 +1166,10 @@ static void cf_ngtcp2_adjust_pollset(struct Curl_cfilter *cf,
+ bool c_exhaust, s_exhaust;
+
+ CF_DATA_SAVE(save, cf, data);
+- c_exhaust = !ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
+- !ngtcp2_conn_get_max_data_left(ctx->qconn);
+- s_exhaust = stream && stream->id >= 0 && stream->quic_flow_blocked;
++ c_exhaust = want_send && (!ngtcp2_conn_get_cwnd_left(ctx->qconn) ||
++ !ngtcp2_conn_get_max_data_left(ctx->qconn));
++ s_exhaust = want_send && stream && stream->id >= 0 &&
++ stream->quic_flow_blocked;
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||
+ !Curl_bufq_is_empty(&ctx->q.sendbuf);
+diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c
+index 33c2621dc8bf63..9c4df2df0f6955 100644
+--- a/lib/vquic/curl_quiche.c
++++ b/lib/vquic/curl_quiche.c
+@@ -1189,7 +1189,7 @@ static void cf_quiche_adjust_pollset(struct Curl_cfilter *cf,
+
+ c_exhaust = FALSE; /* Have not found any call in quiche that tells
+ us if the connection itself is blocked */
+- s_exhaust = stream && stream->id >= 0 &&
++ s_exhaust = want_send && stream && stream->id >= 0 &&
+ (stream->quic_flow_blocked || !stream_is_writeable(cf, data));
+ want_recv = (want_recv || c_exhaust || s_exhaust);
+ want_send = (!s_exhaust && want_send) ||