diff --git a/SOURCES/mod_http2-1.15.7-fix-mood-change.patch b/SOURCES/mod_http2-1.15.7-fix-mood-change.patch new file mode 100644 index 0000000..bb6d3f6 --- /dev/null +++ b/SOURCES/mod_http2-1.15.7-fix-mood-change.patch @@ -0,0 +1,117 @@ +diff --git a/mod_http2/h2_mplx.c b/mod_http2/h2_mplx.c +index e512e22..d5ffdbd 100644 +--- a/mod_http2/h2_mplx.c ++++ b/mod_http2/h2_mplx.c +@@ -868,102 +868,6 @@ void h2_mplx_task_done(h2_mplx *m, h2_task *task, h2_task **ptask) + * h2_mplx DoS protection + ******************************************************************************/ + +-static int timed_out_busy_iter(void *data, void *val) +-{ +- stream_iter_ctx *ctx = data; +- h2_stream *stream = val; +- if (h2_task_has_started(stream->task) && !stream->task->worker_done +- && (ctx->now - stream->task->started_at) > stream->task->timeout) { +- /* timed out stream occupying a worker, found */ +- ctx->stream = stream; +- return 0; +- } +- return 1; +-} +- +-static h2_stream *get_timed_out_busy_stream(h2_mplx *m) +-{ +- stream_iter_ctx ctx; +- ctx.m = m; +- ctx.stream = NULL; +- ctx.now = apr_time_now(); +- h2_ihash_iter(m->streams, timed_out_busy_iter, &ctx); +- return ctx.stream; +-} +- +-static int latest_repeatable_unsubmitted_iter(void *data, void *val) +-{ +- stream_iter_ctx *ctx = data; +- h2_stream *stream = val; +- +- if (!stream->task) goto leave; +- if (!h2_task_has_started(stream->task) || stream->task->worker_done) goto leave; +- if (h2_stream_is_ready(stream)) goto leave; +- if (stream->task->redo) { +- ++ctx->count; +- goto leave; +- } +- if (h2_task_can_redo(stream->task)) { +- /* this task occupies a worker, the response has not been submitted +- * yet, not been cancelled and it is a repeatable request +- * -> we could redo it later */ +- if (!ctx->stream +- || (ctx->stream->task->started_at < stream->task->started_at)) { +- /* we did not have one or this one was started later */ +- ctx->stream = stream; +- } +- } +-leave: +- return 1; +-} +- +-static apr_status_t assess_task_to_throttle(h2_task **ptask, h2_mplx *m) +-{ +- stream_iter_ctx ctx; +- +- /* count the running tasks already marked for redo and get one that could +- * be throttled */ +- *ptask = NULL; +- ctx.m = m; +- ctx.stream = NULL; +- ctx.count = 0; +- h2_ihash_iter(m->streams, latest_repeatable_unsubmitted_iter, &ctx); +- if (m->tasks_active - ctx.count > m->limit_active) { +- /* we are above the limit of running tasks, accounting for the ones +- * already throttled. */ +- if (ctx.stream && ctx.stream->task) { +- *ptask = ctx.stream->task; +- return APR_EAGAIN; +- } +- /* above limit, be seeing no candidate for easy throttling */ +- if (get_timed_out_busy_stream(m)) { +- /* Too many busy workers, unable to cancel enough streams +- * and with a busy, timed out stream, we tell the client +- * to go away... */ +- return APR_TIMEUP; +- } +- } +- return APR_SUCCESS; +-} +- +-static apr_status_t unschedule_slow_tasks(h2_mplx *m) +-{ +- h2_task *task; +- apr_status_t rv; +- +- /* Try to get rid of streams that occupy workers. Look for safe requests +- * that are repeatable. If none found, fail the connection. +- */ +- while (APR_EAGAIN == (rv = assess_task_to_throttle(&task, m))) { +- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, +- "h2_mplx(%s): unschedule, resetting task for redo later", +- task->id); +- task->redo = 1; +- h2_task_rst(task, H2_ERR_CANCEL); +- } +- return rv; +-} +- + static apr_status_t mplx_be_happy(h2_mplx *m, h2_task *task) + { + apr_time_t now; +@@ -1013,9 +917,6 @@ static apr_status_t mplx_be_annoyed(h2_mplx *m) + m->id, m->limit_active); + } + +- if (m->tasks_active > m->limit_active) { +- status = unschedule_slow_tasks(m); +- } + return status; + } + diff --git a/SOURCES/mod_http2-1.15.7-r1918628.patch b/SOURCES/mod_http2-1.15.7-r1918628.patch new file mode 100644 index 0000000..0d3e256 --- /dev/null +++ b/SOURCES/mod_http2-1.15.7-r1918628.patch @@ -0,0 +1,21 @@ +diff --git a/mod_http2/mod_proxy_http2.c b/mod_http2/mod_proxy_http2.c +index c3b2ad5..7443021 100644 +--- a/mod_http2/mod_proxy_http2.c ++++ b/mod_http2/mod_proxy_http2.c +@@ -303,7 +303,7 @@ static int proxy_http2_handler(request_rec *r, + apr_port_t proxyport) + { + const char *proxy_func, *task_id; +- char *locurl = url, *u; ++ char *locurl, *u; + apr_size_t slen; + int is_ssl = 0; + apr_status_t status; +@@ -372,6 +372,7 @@ run_connect: + goto cleanup; + } + ++ locurl = url; + ctx->p_conn->is_ssl = ctx->is_ssl; + + /* Step One: Determine the URL to connect to (might be a proxy), diff --git a/SOURCES/mod_http2-1.15.7-wrong-cl-proxy-resp-handling.patch b/SOURCES/mod_http2-1.15.7-wrong-cl-proxy-resp-handling.patch new file mode 100644 index 0000000..5f2b87d --- /dev/null +++ b/SOURCES/mod_http2-1.15.7-wrong-cl-proxy-resp-handling.patch @@ -0,0 +1,23 @@ +diff --git a/mod_http2/h2_proxy_session.c b/mod_http2/h2_proxy_session.c +index 121c226..5f64dbc 100644 +--- a/mod_http2/h2_proxy_session.c ++++ b/mod_http2/h2_proxy_session.c +@@ -334,6 +334,7 @@ static void h2_proxy_stream_end_headers_out(h2_proxy_stream *stream) + h2_proxy_session *session = stream->session; + request_rec *r = stream->r; + apr_pool_t *p = r->pool; ++ const char *buf; + + /* Now, add in the cookies from the response to the ones already saved */ + apr_table_do(add_header, stream->saves, r->headers_out, "Set-Cookie", NULL); +@@ -343,6 +344,10 @@ static void h2_proxy_stream_end_headers_out(h2_proxy_stream *stream) + apr_table_unset(r->headers_out, "Set-Cookie"); + r->headers_out = apr_table_overlay(p, r->headers_out, stream->saves); + } ++ ++ if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { ++ ap_set_content_type(r, apr_pstrdup(p, buf)); ++ } + + /* handle Via header in response */ + if (session->conf->viaopt != via_off diff --git a/SPECS/mod_http2.spec b/SPECS/mod_http2.spec index 79240ba..0dd6446 100644 --- a/SPECS/mod_http2.spec +++ b/SPECS/mod_http2.spec @@ -3,7 +3,7 @@ Name: mod_http2 Version: 1.15.7 -Release: 10%{?dist}.1 +Release: 10%{?dist}.3 Summary: module implementing HTTP/2 for Apache 2 Group: System Environment/Daemons License: ASL 2.0 @@ -22,6 +22,12 @@ Patch7: mod_http2-1.15.7-CVE-2023-45802.patch Patch8: mod_http2-1.15.7-CVE-2024-27316.patch # https://issues.redhat.com/browse/RHEL-46214 Patch9: mod_http2-1.15.7-log-error-resp.patch +# https://issues.redhat.com/browse/RHEL-71575 +Patch10: mod_http2-1.15.7-wrong-cl-proxy-resp-handling.patch +# https://issues.redhat.com/browse/RHEL-58454 +Patch11: mod_http2-1.15.7-r1918628.patch +# https://issues.redhat.com/browse/RHEL-59017 +Patch12: mod_http2-1.15.7-fix-mood-change.patch BuildRequires: pkgconfig, httpd-devel >= 2.4.20, libnghttp2-devel >= 1.7.0, openssl-devel >= 1.0.2 Requires: httpd-mmn = %{_httpd_mmn} @@ -42,6 +48,9 @@ top of libnghttp2 for httpd 2.4 servers. %patch7 -p1 -b .CVE-2023-45802 %patch8 -p1 -b .CVE-2024-27316 %patch9 -p1 -b .log-error-resp +%patch10 -p1 -b .wrong-cl-proxy-resp-handling +%patch11 -p1 -b .r1918628 +%patch12 -p1 -b .fix-mood-change %build %configure @@ -68,6 +77,14 @@ make check %{_httpd_moddir}/mod_proxy_http2.so %changelog +* Tue Jan 28 2025 Luboš Uhliarik - 1.15.7-10.3 +- Resolves: RHEL-58454 - mod_proxy_http2 failures after CVE-2024-38477 fix +- Resolves: RHEL-59017 - random failures in other requests on http/2 stream + when client resets one request + +* Tue Jan 07 2025 Luboš Uhliarik - 1.15.7-10.2 +- Resolves: RHEL-71575: Wrong Content-Type when proxying using H2 protocol + * Tue Aug 27 2024 Luboš Uhliarik - 1.15.7-10.1 - Resolves: RHEL-46214 - Access logs and ErrorDocument don't work when HTTP431 occurs using http/2 on RHEL8