From c3090a88f6e9a82671fcc123cdb4ce3004f51b75 Mon Sep 17 00:00:00 2001 From: zhaoyonghao Date: Wed, 3 Dec 2025 16:12:51 +0800 Subject: [PATCH] mod_proxy: SetEnv proxy-nohalfclose to disable half-close tunneling (cherry picked from commit 9b5f93d096d16cddb9ae2d364f2f28f56b558c85) --- ...lose-to-disable-half-close-tunneling.patch | 163 ++++++++++++++++++ httpd.spec | 9 +- 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch 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 0000000..93380d1 --- /dev/null +++ b/backport-mod_proxy-SetEnv-proxy-nohalfclose-to-disable-half-close-tunneling.patch @@ -0,0 +1,163 @@ +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:NA +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 00000000000..266cbb7b501 +--- /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 1219e9f1727..35acc49a4a3 100644 +--- a/modules/proxy/mod_proxy.h ++++ b/modules/proxy/mod_proxy.h +@@ -1335,7 +1335,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 4c889d9ed38..a3cf5460487 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -4741,6 +4741,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). + */ +@@ -4846,6 +4851,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 { +@@ -4862,7 +4873,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, +@@ -4897,14 +4908,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) +@@ -4923,7 +4934,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 | +@@ -4932,7 +4944,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; + } + + /* We want to write if we asked for POLLOUT and got: +@@ -4962,7 +4975,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 +@@ -4992,7 +5006,8 @@ PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel) + */ + rc = proxy_tunnel_forward(tunnel, in); + if (rc != OK) { +- return rc; ++ status = rc; ++ goto done; + } + } + } +@@ -5007,15 +5022,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) diff --git a/httpd.spec b/httpd.spec index d961dbc..58144f6 100644 --- a/httpd.spec +++ b/httpd.spec @@ -8,7 +8,7 @@ Name: httpd Summary: Apache HTTP Server Version: 2.4.51 -Release: 25 +Release: 26 License: ASL 2.0 URL: https://httpd.apache.org/ Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -142,6 +142,7 @@ Patch88: backport-CVE-2025-23048.patch patch89: backport-CVE-2024-47252.patch Patch90: backport-CVE-2024-43204.patch Patch91: backport-CVE-2024-42516.patch +Patch92: 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 @@ -578,6 +579,12 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Wed Dec 3 2025 zhaoyonghao - 2.4.51-26 +- Type:bugfix +- CVE: +- SUG:NA +- DESC:mod_proxy: SetEnv proxy-nohalfclose to disable half-close tunneling + * Thu Aug 14 2025 yanglu - 2.4.51-25 - Type:CVE - CVE:CVE-2025-49812,CVE-2025-23048,CVE-2024-47252,CVE-2024-43204,CVE-2024-42516 -- Gitee