diff --git a/SOURCES/httpd-2.4.62-CVE-2024-47252.patch b/SOURCES/httpd-2.4.62-CVE-2024-47252.patch new file mode 100644 index 0000000..df0063a --- /dev/null +++ b/SOURCES/httpd-2.4.62-CVE-2024-47252.patch @@ -0,0 +1,45 @@ +From c01e60707048be14a510f0a92128a5227923215c Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Mon, 7 Jul 2025 12:03:42 +0000 +Subject: [PATCH] backport 1927034 from trunk + + escape ssl vars + +Reviewed By: rpluem, jorton, covener, ylavic + + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927042 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/ssl/ssl_engine_vars.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c +index 418d849e00e..4060c0f6a63 100644 +--- a/modules/ssl/ssl_engine_vars.c ++++ b/modules/ssl/ssl_engine_vars.c +@@ -1208,8 +1208,9 @@ static const char *ssl_var_log_handler_c(request_rec *r, char *a) + result = "-"; + else if (strEQ(a, "errstr")) + result = (char *)sslconn->verify_error; +- if (result != NULL && result[0] == NUL) +- result = NULL; ++ if (result) { ++ result = *result ? ap_escape_logitem(r->pool, result) : NULL; ++ } + return result; + } + +@@ -1222,8 +1223,9 @@ static const char *ssl_var_log_handler_x(request_rec *r, char *a) + char *result; + + result = ssl_var_lookup(r->pool, r->server, r->connection, r, a); +- if (result != NULL && result[0] == NUL) +- result = NULL; ++ if (result) { ++ result = *result ? ap_escape_logitem(r->pool, result) : NULL; ++ } + return result; + } + + diff --git a/SOURCES/httpd-2.4.62-CVE-2025-23048.patch b/SOURCES/httpd-2.4.62-CVE-2025-23048.patch new file mode 100644 index 0000000..d868acb --- /dev/null +++ b/SOURCES/httpd-2.4.62-CVE-2025-23048.patch @@ -0,0 +1,56 @@ +From d76573e7608cbdeab6c6a658c427d900917bf955 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Mon, 7 Jul 2025 11:51:57 +0000 +Subject: [PATCH] update SNI validation + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1927035 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/ssl/ssl_engine_kernel.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index 9c51021..d912a87 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -371,19 +371,6 @@ int ssl_hook_ReadReq(request_rec *r) + " provided in HTTP request", servername); + return HTTP_BAD_REQUEST; + } +- if (r->server != handshakeserver +- && !ssl_server_compatible(sslconn->server, r->server)) { +- /* +- * The request does not select the virtual host that was +- * selected by the SNI and its SSL parameters are different +- */ +- +- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02032) +- "Hostname %s provided via SNI and hostname %s provided" +- " via HTTP have no compatible SSL setup", +- servername, r->hostname); +- return HTTP_MISDIRECTED_REQUEST; +- } + } + else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE) + || hssc->strict_sni_vhost_check == SSL_ENABLED_TRUE) +@@ -404,6 +391,21 @@ int ssl_hook_ReadReq(request_rec *r) + "which is required to access this server.
\n"); + return HTTP_FORBIDDEN; + } ++ if (r->server != handshakeserver ++ && !ssl_server_compatible(sslconn->server, r->server)) { ++ /* ++ * The request does not select the virtual host that was ++ * selected for handshaking and its SSL parameters are different ++ */ ++ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02032) ++ "Hostname %s %s and hostname %s provided" ++ " via HTTP have no compatible SSL setup", ++ servername ? servername : handshakeserver->server_hostname, ++ servername ? "provided via SNI" : "(default host as no SNI was provided)", ++ r->hostname); ++ return HTTP_MISDIRECTED_REQUEST; ++ } + } + #endif + modssl_set_app_data2(ssl, r); diff --git a/SOURCES/httpd-2.4.62-CVE-2025-49812.patch b/SOURCES/httpd-2.4.62-CVE-2025-49812.patch new file mode 100644 index 0000000..3b55e65 --- /dev/null +++ b/SOURCES/httpd-2.4.62-CVE-2025-49812.patch @@ -0,0 +1,198 @@ +From 87a7351c755c9ef8ab386e3090e44838c2a06d48 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Mon, 7 Jul 2025 12:09:30 +0000 +Subject: [PATCH] backport 1927037 from trunk + + remove antiquated 'SSLEngine optional' TLS upgrade + +Reviewed By: rpluem, jorton, covener + + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927045 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/ssl/ssl_engine_config.c | 6 ++- + modules/ssl/ssl_engine_init.c | 6 +-- + modules/ssl/ssl_engine_kernel.c | 86 --------------------------------- + modules/ssl/ssl_private.h | 1 - + 4 files changed, 7 insertions(+), 92 deletions(-) + +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 25f50a2..c5dce7f 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -742,11 +742,13 @@ const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg) + return NULL; + } + else if (!strcasecmp(arg, "Optional")) { +- sc->enabled = SSL_ENABLED_OPTIONAL; ++ sc->enabled = SSL_ENABLED_FALSE; ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(10510) ++ "'SSLEngine optional' is no longer supported"); + return NULL; + } + +- return "Argument must be On, Off, or Optional"; ++ return "Argument must be On or Off"; + } + + const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag) +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index ebb11e9..309a7a4 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -427,7 +427,7 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, + &ssl_module); + + sc = mySrvConfig(s); +- if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) { ++ if (sc->enabled == SSL_ENABLED_TRUE) { + if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) { + return rv; + } +@@ -2152,9 +2152,9 @@ apr_status_t ssl_init_ConfigureServer(server_rec *s, + &ssl_module); + apr_status_t rv; + +- /* Initialize the server if SSL is enabled or optional. ++ /* Initialize the server if SSL is enabled. + */ +- if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) { ++ if (sc->enabled == SSL_ENABLED_TRUE) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914) + "Configuring server %s for SSL protocol", sc->vhost_id); + if ((rv = ssl_init_server_ctx(s, p, ptemp, sc, pphrases)) +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index d912a87..33aa1f7 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -38,59 +38,6 @@ static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); + static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s); + #endif + +-#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols" +-#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1" +-#define CONNECTION_HEADER "Connection: Upgrade" +- +-/* Perform an upgrade-to-TLS for the given request, per RFC 2817. */ +-static apr_status_t upgrade_connection(request_rec *r) +-{ +- struct conn_rec *conn = r->connection; +- apr_bucket_brigade *bb; +- SSLConnRec *sslconn; +- apr_status_t rv; +- SSL *ssl; +- +- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02028) +- "upgrading connection to TLS"); +- +- bb = apr_brigade_create(r->pool, conn->bucket_alloc); +- +- rv = ap_fputs(conn->output_filters, bb, SWITCH_STATUS_LINE CRLF +- UPGRADE_HEADER CRLF CONNECTION_HEADER CRLF CRLF); +- if (rv == APR_SUCCESS) { +- APR_BRIGADE_INSERT_TAIL(bb, +- apr_bucket_flush_create(conn->bucket_alloc)); +- rv = ap_pass_brigade(conn->output_filters, bb); +- } +- +- if (rv) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02029) +- "failed to send 101 interim response for connection " +- "upgrade"); +- return rv; +- } +- +- ssl_init_ssl_connection(conn, r); +- +- sslconn = myConnConfig(conn); +- ssl = sslconn->ssl; +- +- /* Perform initial SSL handshake. */ +- SSL_set_accept_state(ssl); +- SSL_do_handshake(ssl); +- +- if (!SSL_is_init_finished(ssl)) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02030) +- "TLS upgrade handshake failed"); +- ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server); +- +- return APR_ECONNABORTED; +- } +- +- return APR_SUCCESS; +-} +- + /* Perform a speculative (and non-blocking) read from the connection + * filters for the given request, to determine whether there is any + * pending data to read. Return non-zero if there is, else zero. */ +@@ -270,40 +217,17 @@ int ssl_hook_ReadReq(request_rec *r) + { + SSLSrvConfigRec *sc = mySrvConfig(r->server); + SSLConnRec *sslconn; +- const char *upgrade; + #ifdef HAVE_TLSEXT + const char *servername; + #endif + SSL *ssl; + +- /* Perform TLS upgrade here if "SSLEngine optional" is configured, +- * SSL is not already set up for this connection, and the client +- * has sent a suitable Upgrade header. */ +- if (sc->enabled == SSL_ENABLED_OPTIONAL && !myConnConfig(r->connection) +- && (upgrade = apr_table_get(r->headers_in, "Upgrade")) != NULL +- && ap_find_token(r->pool, upgrade, "TLS/1.0")) { +- if (upgrade_connection(r)) { +- return AP_FILTER_ERROR; +- } +- } +- + /* If we are on a slave connection, we do not expect to have an SSLConnRec, + * but our master connection might. */ + sslconn = myConnConfig(r->connection); + if (!(sslconn && sslconn->ssl) && r->connection->master) { + sslconn = myConnConfig(r->connection->master); + } +- +- /* If "SSLEngine optional" is configured, this is not an SSL +- * connection, and this isn't a subrequest, send an Upgrade +- * response header. Note this must happen before map_to_storage +- * and OPTIONS * request processing is completed. +- */ +- if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl) +- && !r->main) { +- apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1"); +- apr_table_mergen(r->headers_out, "Connection", "upgrade"); +- } + + if (!sslconn) { + return DECLINED; +@@ -1238,16 +1162,6 @@ int ssl_hook_Access(request_rec *r) + * Support for SSLRequireSSL directive + */ + if (dc->bSSLRequired && !ssl) { +- if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !r->connection->master) { +- /* This vhost was configured for optional SSL, just tell the +- * client that we need to upgrade. +- */ +- apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1"); +- apr_table_setn(r->err_headers_out, "Connection", "Upgrade"); +- +- return HTTP_UPGRADE_REQUIRED; +- } +- + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219) + "access to %s failed, reason: %s", + r->filename, "SSL connection required"); +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index c517a7b..aaa75aa 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -518,7 +518,6 @@ typedef enum { + SSL_ENABLED_UNSET = UNSET, + SSL_ENABLED_FALSE = 0, + SSL_ENABLED_TRUE = 1, +- SSL_ENABLED_OPTIONAL = 3 + } ssl_enabled_t; + + /** diff --git a/SOURCES/httpd-2.4.62-r1926064.patch b/SOURCES/httpd-2.4.62-r1926064.patch new file mode 100644 index 0000000..350d52f --- /dev/null +++ b/SOURCES/httpd-2.4.62-r1926064.patch @@ -0,0 +1,44 @@ +# ./pullrev.sh 1926064 +http://svn.apache.org/viewvc?view=revision&revision=1926064 + +Since we can't jump from the 2.4.62-level MMN to the 2.4.64-level +MMN added in the upstream 2.4.x backport without adding all other APIs, +this patch defines a custom macro: + + #define AP_X_RH_DAV_GET_BASE_PATH 1 + +which can be tested in the mod_dav_svn code which consumes this. + +--- httpd-2.4.62/modules/dav/main/mod_dav.c ++++ httpd-2.4.62/modules/dav/main/mod_dav.c +@@ -250,6 +250,13 @@ + return dav_get_provider(r)->search; + } + ++DAV_DECLARE(const char *) dav_get_base_path(request_rec *r) ++{ ++ dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module); ++ ++ return conf && conf->base ? conf->base : NULL; ++} ++ + /* + * Command handler for the DAV directive, which is TAKE1. + */ +--- httpd-2.4.62/modules/dav/main/mod_dav.h ++++ httpd-2.4.62/modules/dav/main/mod_dav.h +@@ -430,6 +430,14 @@ + DAV_DECLARE(dav_error *) dav_get_resource(request_rec *r, int label_allowed, + int use_checked_in, dav_resource **res_p); + ++/* Defined for backported dav_get_base_path(). */ ++#define AP_X_RH_DAV_GET_BASE_PATH 1 ++ ++/* ++** If DavBasePath is configured for the request location, return the ++** configured path, otherwise NULL. ++*/ ++DAV_DECLARE(const char *) dav_get_base_path(request_rec *r); + + /* -------------------------------------------------------------------- + ** diff --git a/SOURCES/httpd-2.4.62-r1926107.patch b/SOURCES/httpd-2.4.62-r1926107.patch new file mode 100644 index 0000000..e4a7629 --- /dev/null +++ b/SOURCES/httpd-2.4.62-r1926107.patch @@ -0,0 +1,34 @@ +# ./pullrev.sh 1926107 +http://svn.apache.org/viewvc?view=revision&revision=1926107 + +diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c +index 140366e6d52..daec21ad6c3 100644 +--- a/modules/proxy/mod_proxy_balancer.c ++++ b/modules/proxy/mod_proxy_balancer.c +@@ -276,11 +276,23 @@ static proxy_worker *find_session_route(proxy_balancer *balancer, + char **url) + { + proxy_worker *worker = NULL; ++ char *url_with_qs; + + if (!*balancer->s->sticky) + return NULL; ++ /* ++ * The route might be contained in the query string and *url is not ++ * supposed to contain the query string. Hence add it temporarily if ++ * present. ++ */ ++ if (r->args) { ++ url_with_qs = apr_pstrcat(r->pool, *url, "?", r->args, NULL); ++ } ++ else { ++ url_with_qs = *url; ++ } + /* Try to find the sticky route inside url */ +- *route = get_path_param(r->pool, *url, balancer->s->sticky_path, balancer->s->scolonsep); ++ *route = get_path_param(r->pool, url_with_qs, balancer->s->sticky_path, balancer->s->scolonsep); + if (*route) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01159) + "Found value %s for stickysession %s", + + diff --git a/SOURCES/httpd-2.4.62-r1926317.patch b/SOURCES/httpd-2.4.62-r1926317.patch new file mode 100644 index 0000000..ff0ff9f --- /dev/null +++ b/SOURCES/httpd-2.4.62-r1926317.patch @@ -0,0 +1,454 @@ +From 73360a7509796ea2ed551d3c2cd7661b3703ab0c Mon Sep 17 00:00:00 2001 +From: Yann Ylavic +Date: Tue, 10 Jun 2025 10:43:58 +0000 +Subject: [PATCH] Merge r1912460, r1925743 from trunk: + +mod_proxy: Consistently close the socket on failure to reuse the connection. + +proxy_connection_create() and ap_proxy_connect_backend() sometimes close the +connection on failure, sometimes not. Always close it. + +mod_proxy: restore reuse of ProxyRemote connections when possible. + +Fixes a regression from 2.4.59 (r1913907). + +For a reverse proxy setup with a worker (enablereuse=on) and a +forward/CONNECT ProxyRemote to reach it, an open connection/tunnel +to/through the remote proxy for the same origin server (and using the +same proxy auth) should be reusable. Avoid closing them like r1913534 +did. + +* modules/proxy/proxy_util.c: + Rename the struct to remote_connect_info since it's only used for + connecting through remote CONNECT proxies. Axe the use_http_connect + field, always true. + +* modules/proxy/proxy_util.c(ap_proxy_connection_reusable): + Remote CONNECT (forward) proxy connections can be reused if the auth + and origin server infos are the same, so conn->forward != NULL is not + a condition to prevent reusability. + +* modules/proxy/proxy_util.c(ap_proxy_determine_connection): + Fix the checks around conn->forward reuse and connection cleanup if + that's not possible. + +Submitted by: jfclere, ylavic +Reviewed by: ylavic, jfclere, rpluem + +Github: closes #532 + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1926317 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/proxy/proxy_util.c | 193 ++++++++++++++++++------------------- + 1 file changed, 94 insertions(+), 99 deletions(-) + +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index 7c0d315..cd13401 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -45,16 +45,16 @@ + APLOG_USE_MODULE(proxy); + + /* +- * Opaque structure containing target server info when +- * using a forward proxy. +- * Up to now only used in combination with HTTP CONNECT to ProxyRemote ++ * Opaque structure containing infos for CONNECT-ing an origin server through a ++ * remote (forward) proxy. Saved in the (opaque) proxy_conn_rec::forward pointer ++ * field for backend connections kept alive, allowing for reuse when subsequent ++ * requests should be routed through the same remote proxy. + */ + typedef struct { +- int use_http_connect; /* Use SSL Tunneling via HTTP CONNECT */ +- const char *target_host; /* Target hostname */ +- apr_port_t target_port; /* Target port */ + const char *proxy_auth; /* Proxy authorization */ +-} forward_info; ++ const char *target_host; /* Target/origin hostname */ ++ apr_port_t target_port; /* Target/origin port */ ++} remote_connect_info; + + /* + * Opaque structure containing a refcounted and TTL'ed address. +@@ -1508,6 +1508,7 @@ static void socket_cleanup(proxy_conn_rec *conn) + conn->connection = NULL; + conn->ssl_hostname = NULL; + apr_pool_clear(conn->scpool); ++ conn->close = 0; + } + + static void conn_cleanup(proxy_conn_rec *conn) +@@ -1525,6 +1526,7 @@ static void conn_cleanup(proxy_conn_rec *conn) + + static apr_status_t conn_pool_cleanup(void *theworker) + { ++ /* Signal that the child is exiting */ + ((proxy_worker *)theworker)->cp = NULL; + return APR_SUCCESS; + } +@@ -1603,10 +1605,7 @@ PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn) + { + proxy_worker *worker = conn->worker; + +- return !(conn->close +- || conn->forward +- || worker->s->disablereuse +- || !worker->s->is_address_reusable); ++ return !(conn->close || worker->s->disablereuse); + } + + static proxy_conn_rec *connection_make(apr_pool_t *p, proxy_worker *worker) +@@ -1659,18 +1658,17 @@ static void connection_cleanup(void *theconn) + apr_pool_clear(p); + conn = connection_make(p, worker); + } +- else if (conn->close +- || conn->forward ++ else if (!conn->sock + || (conn->connection + && conn->connection->keepalive == AP_CONN_CLOSE) +- || worker->s->disablereuse) { ++ || !ap_proxy_connection_reusable(conn)) { + socket_cleanup(conn); +- conn->close = 0; + } + else if (conn->is_ssl) { +- /* Unbind/reset the SSL connection dir config (sslconn->dc) from +- * r->per_dir_config, r will likely get destroyed before this proxy +- * conn is reused. ++ /* The current ssl section/dir config of the conn is not necessarily ++ * the one it will be reused for, so while the conn is in the reslist ++ * reset its ssl config to the worker's, until a new user sets its own ++ * ssl config eventually in proxy_connection_create() and so on. + */ + ap_proxy_ssl_engine(conn->connection, worker->section_config, 1); + } +@@ -2800,7 +2798,6 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, + (int)worker->s->port); + + (*conn)->worker = worker; +- (*conn)->close = 0; + (*conn)->inreslist = 0; + + return OK; +@@ -3245,7 +3242,6 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + /* Close a possible existing socket if we are told to do so */ + if (conn->close) { + socket_cleanup(conn); +- conn->close = 0; + } + + /* +@@ -3311,12 +3307,10 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + uri->scheme, conn->uds_path, conn->hostname, conn->port); + } + else { ++ remote_connect_info *connect_info = NULL; + const char *hostname = uri->hostname; + apr_port_t hostport = uri->port; + +- /* Not a remote CONNECT until further notice */ +- conn->forward = NULL; +- + if (proxyname) { + hostname = proxyname; + hostport = proxyport; +@@ -3327,7 +3321,6 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + * sending our actual HTTPS requests. + */ + if (conn->is_ssl) { +- forward_info *forward; + const char *proxy_auth; + + /* Do we want to pass Proxy-Authorization along? +@@ -3346,13 +3339,15 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + proxy_auth = NULL; + } + +- /* Reset forward info if they changed */ +- if (!(forward = conn->forward) +- || forward->target_port != uri->port +- || ap_cstr_casecmp(forward->target_host, uri->hostname) != 0 +- || (forward->proxy_auth != NULL) != (proxy_auth != NULL) +- || (forward->proxy_auth != NULL && proxy_auth != NULL && +- strcmp(forward->proxy_auth, proxy_auth) != 0)) { ++ /* Save our real backend data for using it later during HTTP CONNECT */ ++ connect_info = conn->forward; ++ if (!connect_info ++ /* reset connect info if they changed */ ++ || connect_info->target_port != uri->port ++ || ap_cstr_casecmp(connect_info->target_host, uri->hostname) != 0 ++ || (connect_info->proxy_auth != NULL) != (proxy_auth != NULL) ++ || (connect_info->proxy_auth != NULL && proxy_auth != NULL && ++ strcmp(connect_info->proxy_auth, proxy_auth) != 0)) { + apr_pool_t *fwd_pool = conn->pool; + if (worker->s->is_address_reusable) { + if (conn->fwd_pool) { +@@ -3363,26 +3358,24 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + } + fwd_pool = conn->fwd_pool; + } +- forward = apr_pcalloc(fwd_pool, sizeof(forward_info)); +- conn->forward = forward; +- +- /* +- * Save our real backend data for using it later during HTTP CONNECT. +- */ +- forward->use_http_connect = 1; +- forward->target_host = apr_pstrdup(fwd_pool, uri->hostname); +- forward->target_port = uri->port; ++ connect_info = apr_pcalloc(fwd_pool, sizeof(*connect_info)); ++ connect_info->target_host = apr_pstrdup(fwd_pool, uri->hostname); ++ connect_info->target_port = uri->port; + if (proxy_auth) { +- forward->proxy_auth = apr_pstrdup(fwd_pool, proxy_auth); ++ connect_info->proxy_auth = apr_pstrdup(fwd_pool, proxy_auth); + } ++ conn->forward = NULL; + } + } + } + +- if (conn->hostname +- && (conn->port != hostport +- || ap_cstr_casecmp(conn->hostname, hostname) != 0)) { ++ /* Close the connection if the remote proxy or origin server don't match */ ++ if (conn->forward != connect_info ++ || (conn->hostname ++ && (conn->port != hostport ++ || ap_cstr_casecmp(conn->hostname, hostname) != 0))) { + conn_cleanup(conn); ++ conn->forward = connect_info; + } + + /* Resolve the connection address with the determined hostname/port */ +@@ -3426,9 +3419,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + if (dconf->preserve_host) { + ssl_hostname = r->hostname; + } +- else if (conn->forward +- && ((forward_info *)(conn->forward))->use_http_connect) { +- ssl_hostname = ((forward_info *)conn->forward)->target_host; ++ else if (conn->forward) { ++ ssl_hostname = ((remote_connect_info *)conn->forward)->target_host; + } + else { + ssl_hostname = conn->hostname; +@@ -3525,7 +3517,7 @@ PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *sock) + + + /* +- * Send a HTTP CONNECT request to a forward proxy. ++ * Send a HTTP CONNECT request to a remote proxy. + * The proxy is given by "backend", the target server + * is contained in the "forward" member of "backend". + */ +@@ -3538,24 +3530,24 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend, + int complete = 0; + char buffer[HUGE_STRING_LEN]; + char drain_buffer[HUGE_STRING_LEN]; +- forward_info *forward = (forward_info *)backend->forward; ++ remote_connect_info *connect_info = backend->forward; + int len = 0; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00948) + "CONNECT: sending the CONNECT request for %s:%d " + "to the remote proxy %pI (%s)", +- forward->target_host, forward->target_port, ++ connect_info->target_host, connect_info->target_port, + backend->addr, backend->hostname); + /* Create the CONNECT request */ + nbytes = apr_snprintf(buffer, sizeof(buffer), + "CONNECT %s:%d HTTP/1.0" CRLF, +- forward->target_host, forward->target_port); ++ connect_info->target_host, connect_info->target_port); + /* Add proxy authorization from the configuration, or initial + * request if necessary */ +- if (forward->proxy_auth != NULL) { ++ if (connect_info->proxy_auth != NULL) { + nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes, + "Proxy-Authorization: %s" CRLF, +- forward->proxy_auth); ++ connect_info->proxy_auth); + } + /* Set a reasonable agent and send everything */ + nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes, +@@ -3599,7 +3591,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend, + char code_str[4]; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00949) +- "send_http_connect: response from the forward proxy: %s", ++ "send_http_connect: response from the remote proxy: %s", + buffer); + + /* Extract the returned code */ +@@ -3610,7 +3602,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend, + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00950) +- "send_http_connect: the forward proxy returned code is '%s'", ++ "send_http_connect: the remote proxy returned code is '%s'", + code_str); + status = APR_INCOMPLETE; + } +@@ -3774,7 +3766,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + { + apr_status_t rv; + int loglevel; +- forward_info *forward = conn->forward; ++ remote_connect_info *connect_info = conn->forward; + apr_sockaddr_t *backend_addr; + /* the local address to use for the outgoing connection */ + apr_sockaddr_t *local_addr; +@@ -3975,27 +3967,25 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + + conn->sock = newsock; + +- if (forward && forward->use_http_connect) { +- /* +- * For HTTP CONNECT we need to prepend CONNECT request before +- * sending our actual HTTPS requests. +- */ +- { +- rv = send_http_connect(conn, s); +- /* If an error occurred, loop round and try again */ +- if (rv != APR_SUCCESS) { +- conn->sock = NULL; +- apr_socket_close(newsock); +- loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; +- ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00958) +- "%s: attempt to connect to %s:%hu " +- "via http CONNECT through %pI (%s:%hu) failed", +- proxy_function, +- forward->target_host, forward->target_port, +- backend_addr, conn->hostname, conn->port); +- backend_addr = backend_addr->next; +- continue; +- } ++ /* ++ * For HTTP CONNECT we need to prepend CONNECT request before ++ * sending our actual HTTPS requests. ++ */ ++ if (connect_info) { ++ rv = send_http_connect(conn, s); ++ /* If an error occurred, loop round and try again */ ++ if (rv != APR_SUCCESS) { ++ conn->sock = NULL; ++ apr_socket_close(newsock); ++ loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; ++ ap_log_error(APLOG_MARK, loglevel, rv, s, APLOGNO(00958) ++ "%s: attempt to connect to %s:%hu " ++ "via http CONNECT through %pI (%s:%hu) failed", ++ proxy_function, ++ connect_info->target_host, connect_info->target_port, ++ backend_addr, conn->hostname, conn->port); ++ backend_addr = backend_addr->next; ++ continue; + } + } + } +@@ -4036,13 +4026,13 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, + * e.g. for a timeout or bad status. We should respect this and should + * not continue with a connection via this worker even if we got one. + */ +- if (rv == APR_SUCCESS) { +- socket_cleanup(conn); +- } + rv = APR_EINVAL; + } +- +- return rv == APR_SUCCESS ? OK : DECLINED; ++ if (rv != APR_SUCCESS) { ++ socket_cleanup(conn); ++ return DECLINED; ++ } ++ return OK; + } + + static apr_status_t connection_shutdown(void *theconn) +@@ -4079,9 +4069,9 @@ static int proxy_connection_create(const char *proxy_function, + ap_conf_vector_t *per_dir_config = (r) ? r->per_dir_config + : conn->worker->section_config; + apr_sockaddr_t *backend_addr = conn->addr; +- int rc; + apr_interval_time_t current_timeout; + apr_bucket_alloc_t *bucket_alloc; ++ int rc = OK; + + if (conn->connection) { + if (conn->is_ssl) { +@@ -4093,15 +4083,15 @@ static int proxy_connection_create(const char *proxy_function, + return OK; + } + +- bucket_alloc = apr_bucket_alloc_create(conn->scpool); +- conn->tmp_bb = apr_brigade_create(conn->scpool, bucket_alloc); +- /* +- * The socket is now open, create a new backend server connection +- */ +- conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock, +- 0, NULL, +- bucket_alloc); +- ++ if (conn->sock) { ++ bucket_alloc = apr_bucket_alloc_create(conn->scpool); ++ conn->tmp_bb = apr_brigade_create(conn->scpool, bucket_alloc); ++ /* ++ * The socket is now open, create a new backend server connection ++ */ ++ conn->connection = ap_run_create_connection(conn->scpool, s, conn->sock, ++ 0, NULL, bucket_alloc); ++ } + if (!conn->connection) { + /* + * the peer reset the connection already; ap_run_create_connection() +@@ -4109,11 +4099,11 @@ static int proxy_connection_create(const char *proxy_function, + */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, + s, APLOGNO(00960) "%s: an error occurred creating a " +- "new connection to %pI (%s)", proxy_function, +- backend_addr, conn->hostname); +- /* XXX: Will be closed when proxy_conn is closed */ +- socket_cleanup(conn); +- return HTTP_INTERNAL_SERVER_ERROR; ++ "new connection to %pI (%s)%s", ++ proxy_function, backend_addr, conn->hostname, ++ conn->sock ? "" : " (not connected)"); ++ rc = HTTP_INTERNAL_SERVER_ERROR; ++ goto cleanup; + } + + /* For ssl connection to backend */ +@@ -4123,7 +4113,8 @@ static int proxy_connection_create(const char *proxy_function, + s, APLOGNO(00961) "%s: failed to enable ssl support " + "for %pI (%s)", proxy_function, + backend_addr, conn->hostname); +- return HTTP_INTERNAL_SERVER_ERROR; ++ rc = HTTP_INTERNAL_SERVER_ERROR; ++ goto cleanup; + } + if (conn->ssl_hostname) { + /* Set a note on the connection about what CN is requested, +@@ -4158,7 +4149,7 @@ static int proxy_connection_create(const char *proxy_function, + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00963) + "%s: pre_connection setup failed (%d)", + proxy_function, rc); +- return rc; ++ goto cleanup; + } + apr_socket_timeout_set(conn->sock, current_timeout); + +@@ -4168,6 +4159,10 @@ static int proxy_connection_create(const char *proxy_function, + apr_pool_pre_cleanup_register(conn->scpool, conn, connection_shutdown); + + return OK; ++ ++cleanup: ++ socket_cleanup(conn); ++ return rc; + } + + PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function, +-- +2.44.0 + diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 8495da6..74b9b19 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -13,7 +13,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.62 -Release: 4%{?dist} +Release: 7%{?dist} URL: https://httpd.apache.org/ Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc @@ -88,6 +88,10 @@ Patch33: httpd-2.4.62-freebind.patch Patch34: httpd-2.4.53-separate-systemd-fns.patch # https://issues.redhat.com/browse/RHEL-5071 Patch35: httpd-2.4.57-r1912477+.patch +# https://issues.redhat.com/browse/RHEL-41069 +Patch36: httpd-2.4.62-r1926064.patch +# https://issues.redhat.com/browse/RHEL-106043 +Patch37: httpd-2.4.62-r1926317.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -102,12 +106,17 @@ Patch103: httpd-2.4.62-engine-fallback.patch Patch104: httpd-2.4.62-r1921299.patch # https://issues.redhat.com/browse/RHEL-66488 Patch105: httpd-2.4.62-r1922080.patch +# https://issues.redhat.com/browse/RHEL-99815 +Patch106: httpd-2.4.62-r1926107.patch # Security fixes -# https://bugzilla.redhat.com/show_bug.cgi?id=... # -# https://bugzilla.redhat.com/show_bug.cgi?id= -# Patch200: httpd-2.4.X-CVE-XXXX-YYYYY.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2374576 +Patch200: httpd-2.4.62-CVE-2025-23048.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2374571 +Patch201: httpd-2.4.62-CVE-2024-47252.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2374580 +Patch202: httpd-2.4.62-CVE-2025-49812.patch License: ASL 2.0 @@ -260,6 +269,8 @@ written in the Lua programming language. %patch33 -p1 -b .freebind %patch34 -p1 -b .separatesystemd %patch35 -p1 -b .r1912477+ +%patch36 -p1 -b .r1926064 +%patch37 -p1 -b .r1926317 %patch100 -p1 -b .enable-sslv3 %patch101 -p1 -b .full-release @@ -267,6 +278,11 @@ written in the Lua programming language. %patch103 -p0 -b .engine-fallback %patch104 -p1 -b .r1921299 %patch105 -p1 -b .r1922080 +%patch106 -p1 -b .r1926107 + +%patch200 -p1 -b .CVE-2025-23048 +%patch201 -p1 -b .CVE-2024-47252 +%patch202 -p1 -b .CVE-2025-49812 # Patch in the vendor string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -828,6 +844,24 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Sat Aug 16 2025 Luboš Uhliarik - 2.4.62-7 +- Resolves: RHEL-99815 - stickysession field does not work when specifying + it in the query parameter after upgrade to 9.5 +- Resolves: RHEL-99953 - httpd: HTTP Session Hijack via a TLS + upgrade (CVE-2025-49812) +- Resolves: RHEL-99968 - httpd: access control bypass by trusted + clients is possible using TLS 1.3 session resumption (CVE-2025-23048) +- Resolves: RHEL-99977 - httpd: insufficient escaping of user-supplied + data in mod_ssl (CVE-2024-47252) + +* Tue Jul 29 2025 Luboš Uhliarik - 2.4.62-6 +- Resolves: RHEL-94562 - httpd 2.4.62: mod_proxy_connect prematurely closes + connections + +* Fri Jun 06 2025 Joe Orton - 2.4.62-5 +- mod_dav: add dav_get_base_path() API +- Resolves: RHEL-41069 + * Wed Jan 29 2025 Luboš Uhliarik - 2.4.62-4 - Resolves: RHEL-66488 - Apache HTTPD no longer parse PHP files with unicode characters in the name