diff --git a/backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch b/backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch new file mode 100644 index 0000000000000000000000000000000000000000..3da300a286b163b16884bc4290f9ed387938a7ce --- /dev/null +++ b/backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch @@ -0,0 +1,168 @@ +From ff0c3b5ad2d7a1f527785398c094b82e3e29baf6 Mon Sep 17 00:00:00 2001 +From: Yann Ylavic +Date: Wed, 24 Nov 2021 17:49:47 +0000 +Subject: [PATCH] mod_proxy: SetEnv proxy-nohalfclose to disable half-close + tunneling. PR 65662. + +Some connect/wstunnel protocols might want half-close forwarding while some +might not, let's provide an r->subprocess_env opt-out. + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895304 13f79535-47bb-0310-9956-ffa450edef68 +(cherry picked from commit 5338e45798e2be5296b57c5b31c0de763f2d8962) + +Conflict:context adapt +Reference:https://github.com/apache/httpd/commit/ff0c3b5ad2d7a1f527785398c094b82e3e29baf6 + +--- + changes-entries/proxy_half_close.txt | 2 ++ + modules/proxy/mod_proxy.h | 3 +- + modules/proxy/proxy_util.c | 42 ++++++++++++++++++++-------- + 3 files changed, 35 insertions(+), 12 deletions(-) + create mode 100644 changes-entries/proxy_half_close.txt + +diff --git a/changes-entries/proxy_half_close.txt b/changes-entries/proxy_half_close.txt +new file mode 100644 +index 0000000..266cbb7 +--- /dev/null ++++ b/changes-entries/proxy_half_close.txt +@@ -0,0 +1,2 @@ ++ *) mod_proxy: SetEnv proxy-nohalfclose (or alike) allows to disable TCP ++ half-close forwarding when tunneling protocols. [Yann Ylavic] +diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h +index 0a8e1c4..f50fb2e 100644 +--- a/modules/proxy/mod_proxy.h ++++ b/modules/proxy/mod_proxy.h +@@ -1213,7 +1213,8 @@ typedef struct { + struct proxy_tunnel_conn *client, + *origin; + apr_size_t read_buf_size; +- int replied; ++ int replied; /* TODO 2.5+: one bit to merge in below bitmask */ ++ unsigned int nohalfclose :1; + } proxy_tunnel_rec; + + /** +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index a9c21ad..bc7cddf 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -4329,6 +4329,11 @@ PROXY_DECLARE(apr_status_t) ap_proxy_tunnel_create(proxy_tunnel_rec **ptunnel, + c_i->keepalive = AP_CONN_CLOSE; + c_o->keepalive = AP_CONN_CLOSE; + ++ /* Disable half-close forwarding for this request? */ ++ if (apr_table_get(r->subprocess_env, "proxy-nohalfclose")) { ++ tunnel->nohalfclose = 1; ++ } ++ + /* Start with POLLOUT and let ap_proxy_tunnel_run() schedule both + * directions when there are no output data pending (anymore). + */ +@@ -4434,6 +4439,12 @@ static int proxy_tunnel_forward(proxy_tunnel_rec *tunnel, + ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, tunnel->r, + "proxy: %s: %s read shutdown", + tunnel->scheme, in->name); ++ if (tunnel->nohalfclose) { ++ /* No half-close forwarding, we are done both ways as ++ * soon as one side shuts down. ++ */ ++ return DONE; ++ } + in->down_in = 1; + } + else { +@@ -4450,7 +4461,7 @@ static int proxy_tunnel_forward(proxy_tunnel_rec *tunnel, + + PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + { +- int rc = OK; ++ int status = OK, rc; + request_rec *r = tunnel->r; + apr_pollset_t *pollset = tunnel->pollset; + struct proxy_tunnel_conn *client = tunnel->client, +@@ -4485,14 +4496,14 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + "(client=%hx, origin=%hx)", + scheme, client->pfd->reqevents, + origin->pfd->reqevents); +- rc = HTTP_GATEWAY_TIME_OUT; ++ status = HTTP_GATEWAY_TIME_OUT; + } + else { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(10214) + "proxy: %s: polling failed", scheme); +- rc = HTTP_INTERNAL_SERVER_ERROR; ++ status = HTTP_INTERNAL_SERVER_ERROR; + } +- return rc; ++ goto done; + } + + ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(10215) +@@ -4511,7 +4522,8 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + && pfd->desc.s != origin->pfd->desc.s) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10222) + "proxy: %s: unknown socket in pollset", scheme); +- return HTTP_INTERNAL_SERVER_ERROR; ++ status = HTTP_INTERNAL_SERVER_ERROR; ++ goto done; + } + + if (!(pfd->rtnevents & (APR_POLLIN | APR_POLLOUT | +@@ -4520,7 +4532,8 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10220) + "proxy: %s: polling events error (%x)", + scheme, pfd->rtnevents); +- return HTTP_INTERNAL_SERVER_ERROR; ++ status = HTTP_INTERNAL_SERVER_ERROR; ++ goto done; + } + + /* Write if we asked for POLLOUT, and got it or POLLERR +@@ -4546,7 +4559,8 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10221) + "proxy: %s: %s flushing failed (%i)", + scheme, out->name, rc); +- return rc; ++ status = rc; ++ goto done; + } + + /* No more pending data. If the other side is not readable +@@ -4574,7 +4588,8 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + if (ap_filter_input_pending(in->c) == OK) { + rc = proxy_tunnel_forward(tunnel, in); + if (rc != OK) { +- return rc; ++ status = rc; ++ goto done; + } + } + } +@@ -4589,15 +4604,20 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + || !(pfd->rtnevents & APR_POLLOUT))) { + rc = proxy_tunnel_forward(tunnel, tc); + if (rc != OK) { +- return rc; ++ status = rc; ++ goto done; + } + } + } + } while (!client->down_out || !origin->down_out); + ++done: + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(10223) +- "proxy: %s: tunnel finished", scheme); +- return OK; ++ "proxy: %s: tunneling returns (%i)", scheme, status); ++ if (status == DONE) { ++ status = OK; ++ } ++ return status; + } + + PROXY_DECLARE (const char *) ap_proxy_show_hcmethod(hcmethod_t method) +-- +2.43.0 + diff --git a/httpd.spec b/httpd.spec index cc64828e80cfa8f278794f6a7ee164217ab6d52b..333539c6fd42f07dd321c0d2b2918251fcf1c740 100644 --- a/httpd.spec +++ b/httpd.spec @@ -8,7 +8,7 @@ Name: httpd Summary: Apache HTTP Server Version: 2.4.43 -Release: 29 +Release: 30 License: ASL 2.0 URL: https://httpd.apache.org/ Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -135,6 +135,7 @@ Patch81: backport-CVE-2025-23048.patch Patch82: backport-CVE-2024-47252.patch Patch83: backport-CVE-2024-43204.patch Patch84: backport-CVE-2024-42516.patch +Patch85: backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel @@ -571,6 +572,12 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Wed Dec 3 2025 zhaoyonghao - 2.4.43-30 +- Type:bugfix +- CVE: +- SUG:NA +- DESC:SetEnv proxy-nohalfclose to disable half-close tunneling + * Tue Dec 2 2025 gongxingliang - 2.4.43-29 - Type:bugfix - Id:NA