SHA256
1
0
forked from pool/apache2

17 Commits

Author SHA256 Message Date
356bfd0a6f Fix 4 bugs/CVEs.
- Fix the following bugs and CVEs:
  * bsc#1254511 / CVE-2025-55753
  * bsc#1254512 / CVE-2025-58098
  * bsc#1254514 / CVE-2025-65082
  * bsc#1254515 / CVE-2025-66200
- Add patches:
  * CVE-2025-55753.patch
  * CVE-2025-58098.patch
  * CVE-2025-65082.patch
  * CVE-2025-66200.patch
2025-12-16 21:16:44 +01:00
1aaedef3aa Sync changes to SLFO-1.2 branch 2025-08-20 09:03:01 +02:00
5e2a6b06f3 Accepting request 1295323 from Apache
OBS-URL: https://build.opensuse.org/request/show/1295323
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=218
2025-07-25 15:03:56 +00:00
1177533e53 - version update to 2.4.65
*) SECURITY: CVE-2025-54090: Apache HTTP Server: 'RewriteCond expr'
     always evaluates to true in 2.4.64 (cve.mitre.org)
     A bug in Apache HTTP Server 2.4.64 results in all "RewriteCond
     expr ..." tests evaluating as "true".
     Users are recommended to upgrade to version 2.4.65, which fixes
     the issue.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=721
2025-07-23 12:56:49 +00:00
3a0ed9cf2d Accepting request 1294249 from Apache
OBS-URL: https://build.opensuse.org/request/show/1294249
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=217
2025-07-20 13:28:01 +00:00
e4531db3a3 * Refresh patches:
- apache-test-application-xml-type.patch
  - apache-test-turn-off-variables-in-ssl-var-lookup.patch
  - apache2-HttpContentLengthHeadZero-HttpExpectStrict.patch
  - apache2-LimitRequestFieldSize-limits-headers.patch
* Update to 2.4.64.
* CVE-2025-53020: Apache HTTP Server: HTTP/2 DoS by Memory Increase
* CVE-2025-49812: Apache HTTP Server: mod_ssl TLS upgrade attack
* CVE-2025-49630: Apache HTTP Server: mod_proxy_http2 denial of service
* CVE-2025-23048: Apache HTTP Server: mod_ssl access control bypass with session resumption
* CVE-2024-47252: Apache HTTP Server: mod_ssl error log variable escaping
* CVE-2024-43394: Apache HTTP Server: SSRF on Windows due to UNC paths
* CVE-2024-43204: Apache HTTP Server: SSRF with mod_headers setting Content-Type header
* CVE-2024-42516: Apache HTTP Server: HTTP response splitting
* mod_proxy_ajp: Use iobuffersize set on worker level for the IO buffer
  size.
* mod_ssl: Drop $SSLKEYLOGFILE handling internally for OpenSSL 3.5
  builds which enable it in libssl natively.
* mod_asis: Fix the log level of the message AH01236.
* mod_session_dbd: ensure format used with SessionDBDCookieName and
  SessionDBDCookieName2 are correct.
* mod_headers: 'RequestHeader set|edit|edit_r Content-Type X' could
  inadvertently modify the Content-Type _response_ header. Applies to
  Content-Type only and likely to only affect static file responses.
* mod_ssl: Remove warning over potential uninitialised value
  for ssl protocol prior to protocol selection.
* mod_proxy: Reuse ProxyRemote connections when possible, like prior
  to 2.4.59.
* mod_systemd: Add systemd socket activation support.
* mod_systemd: Log the SELinux context at startup if available and

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=719
2025-07-18 03:49:15 +00:00
26adddb99d Accepting request 1251625 from Apache
OBS-URL: https://build.opensuse.org/request/show/1251625
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=216
2025-03-11 19:43:41 +00:00
285b0fe9bf - Update to 2.4.63:
* mod_dav: Update redirect-carefully example BrowserMatch config
    to match more recent client versions.
  * mod_cache_socache: Fix possible crash on error path.
  * mod_ssl: Fail cleanly at startup if OpenSSL initialization fails.
  * mod_md: update to version 2.4.31
    - Improved error reporting when waiting for ACME server to verify
      domains or finalizing the order fails, e.g. times out.
    - Increasing the timeouts to wait for ACME server to verify domain
      names and issue the certificate from 30 seconds to 5 minutes.
    - Change a log level from error to debug when Stapling is enabled
      but a certificate carries no OCSP responder URL.
  * mod_proxy_balancer: Fix the handling of the stickysession
    configuration parameter by the balancer manager.
  * Add the ldap-search option to mod_authnz_ldap, allowing
    authorization to be based on arbitrary expressions that do not
    include the username.  Make sure that when ldap searches are too
    long, we explicitly log the error.
  * mod_proxy: Honor parameters of ProxyPassMatch workers with substitution
    in the host name or port.
  * mod_log_config: Fix merging for the "LogFormat" directive.
  * mod_lua: Make r.ap_auth_type writable.
  * mod_md: update to version 2.4.29
    - Fixed HTTP-01 challenges to not carry a final newline, as some
      ACME server fail to ignore it.
    - Fixed missing label+newline in server-status plain text output
      when MDStapling is enabled.
  * mod_ssl: Restore support for loading PKCS#11 keys via ENGINE
    without "SSLCryptoDevice" configured.
  * mod_authnz_ldap: Fix possible memory corruption if the

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=717
2025-03-10 05:09:18 +00:00
4f979fbc59 Accepting request 1251234 from Apache
Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1251234
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=215
2025-03-08 16:51:31 +00:00
0299bc148b - Require main apache2 package in MPM packages (boo#1226379)
OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=715
2025-03-07 15:18:26 +00:00
2bde2c8dc7 Accepting request 1237712 from Apache
- Fix builds of test package with RPM 4.20:
  + noarch packages cannot rely on libdir, which is an
    arch-dependent variable. Rely on apxs -q libdir to extract the
    correct information instead. (forwarded request 1237660 from dimstar)

OBS-URL: https://build.opensuse.org/request/show/1237712
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=214
2025-01-15 16:42:06 +00:00
7e57f4d1e3 - Fix builds of test package with RPM 4.20:
+ noarch packages cannot rely on libdir, which is an
    arch-dependent variable. Rely on apxs -q libdir to extract the
    correct information instead.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=713
2025-01-14 10:27:27 +00:00
ff8f362dac Accepting request 1221591 from Apache
OBS-URL: https://build.opensuse.org/request/show/1221591
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=213
2024-11-06 15:49:13 +00:00
e7ac9d37d9 - Update httpd-framework to svn1921782.
- Fixes Apache's impact on bsc#1218342.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=711
2024-11-05 18:24:44 +00:00
62e3b1fe7e - Explicitly mark start_apache2 as bash-dependent.
If you have dash-sh installed, apache2 completely fails to start:

Nov 04 21:52:14 f3 start_apache2[55066]: /usr/sbin/start_apache2: 158: Syntax error: "(" unexpected

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=710
2024-11-05 18:14:23 +00:00
9695f91e0b Accepting request 1205314 from Apache
OBS-URL: https://build.opensuse.org/request/show/1205314
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=212
2024-10-03 15:59:19 +00:00
3684930e1f - Add /srv/www directories to filelist [bsc#1231027]
(apache2 will not start since default config uses this directory)

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=708
2024-10-02 19:42:36 +00:00
20 changed files with 5752 additions and 30 deletions

303
CVE-2024-42516.patch Normal file
View File

@@ -0,0 +1,303 @@
From a7a9d814c7c23e990283277230ddd5a9efec27c7 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 11:59:38 +0000
Subject: [PATCH] fix header merging
Reviewed By: rpluem, jorton, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927039 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http/http_filters.c | 248 +++++++++++++++++++-----------------
1 file changed, 128 insertions(+), 120 deletions(-)
Index: httpd-2.4.58/modules/http/http_filters.c
===================================================================
--- httpd-2.4.58.orig/modules/http/http_filters.c
+++ httpd-2.4.58/modules/http/http_filters.c
@@ -1300,107 +1300,10 @@ typedef struct header_filter_ctx {
int headers_sent;
} header_filter_ctx;
-AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
- apr_bucket_brigade *b)
+static void merge_response_headers(request_rec *r, const char **protocol)
{
- request_rec *r = f->r;
- conn_rec *c = r->connection;
- const char *clheader;
- int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
- const char *protocol = NULL;
- apr_bucket *e;
- apr_bucket_brigade *b2;
- header_struct h;
- header_filter_ctx *ctx = f->ctx;
- const char *ctype;
- ap_bucket_error *eb = NULL;
- apr_status_t rv = APR_SUCCESS;
- int recursive_error = 0;
-
- AP_DEBUG_ASSERT(!r->main);
-
- if (!ctx) {
- ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
- }
- else if (ctx->headers_sent) {
- /* Eat body if response must not have one. */
- if (header_only) {
- /* Still next filters may be waiting for EOS, so pass it (alone)
- * when encountered and be done with this filter.
- */
- e = APR_BRIGADE_LAST(b);
- if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
- APR_BUCKET_REMOVE(e);
- apr_brigade_cleanup(b);
- APR_BRIGADE_INSERT_HEAD(b, e);
- ap_remove_output_filter(f);
- rv = ap_pass_brigade(f->next, b);
- }
- apr_brigade_cleanup(b);
- return rv;
- }
- }
-
- for (e = APR_BRIGADE_FIRST(b);
- e != APR_BRIGADE_SENTINEL(b);
- e = APR_BUCKET_NEXT(e))
- {
- if (AP_BUCKET_IS_ERROR(e) && !eb) {
- eb = e->data;
- continue;
- }
- /*
- * If we see an EOC bucket it is a signal that we should get out
- * of the way doing nothing.
- */
- if (AP_BUCKET_IS_EOC(e)) {
- ap_remove_output_filter(f);
- return ap_pass_brigade(f->next, b);
- }
- }
-
- if (!ctx->headers_sent && !check_headers(r)) {
- /* We may come back here from ap_die() below,
- * so clear anything from this response.
- */
- apr_table_clear(r->headers_out);
- apr_table_clear(r->err_headers_out);
- r->content_type = r->content_encoding = NULL;
- r->content_languages = NULL;
- r->clength = r->chunked = 0;
- apr_brigade_cleanup(b);
-
- /* Don't recall ap_die() if we come back here (from its own internal
- * redirect or error response), otherwise we can end up in infinite
- * recursion; better fall through with 500, minimal headers and an
- * empty body (EOS only).
- */
- if (!check_headers_recursion(r)) {
- ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
- return AP_FILTER_ERROR;
- }
- r->status = HTTP_INTERNAL_SERVER_ERROR;
- e = ap_bucket_eoc_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- e = apr_bucket_eos_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- ap_set_content_length(r, 0);
- recursive_error = 1;
- }
- else if (eb) {
- int status;
- status = eb->status;
- apr_brigade_cleanup(b);
- ap_die(status, r);
- return AP_FILTER_ERROR;
- }
-
- if (r->assbackwards) {
- r->sent_bodyct = 1;
- ap_remove_output_filter(f);
- rv = ap_pass_brigade(f->next, b);
- goto out;
- }
+ const char *ctype = NULL;
+ const char *clheader = NULL;
/*
* Now that we are ready to send a response, we need to combine the two
@@ -1430,6 +1333,9 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
fixup_vary(r);
}
+ /* determine the protocol and whether we should use keepalives. */
+ basic_http_header_check(r, protocol);
+ ap_set_keepalive(r);
/*
* Control cachability for non-cacheable responses if not already set by
@@ -1449,10 +1355,6 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
apr_table_unset(r->headers_out, "ETag");
}
- /* determine the protocol and whether we should use keepalives. */
- basic_http_header_check(r, &protocol);
- ap_set_keepalive(r);
-
/* 204/304 responses don't have content related headers */
if (AP_STATUS_IS_HEADER_ONLY(r->status)) {
apr_table_unset(r->headers_out, "Transfer-Encoding");
@@ -1520,30 +1422,136 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
&& conf->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_ENABLE) {
apr_table_unset(r->headers_out, "Content-Length");
}
+}
- b2 = apr_brigade_create(r->pool, c->bucket_alloc);
- basic_http_header(r, b2, protocol);
-
- h.pool = r->pool;
- h.bb = b2;
+AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
+ apr_bucket_brigade *b)
+{
+ request_rec *r = f->r;
+ conn_rec *c = r->connection;
+ int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
+ apr_bucket *e;
+ apr_bucket_brigade *b2;
+ header_struct h;
+ header_filter_ctx *ctx = f->ctx;
+ ap_bucket_error *eb = NULL;
+ apr_status_t rv = APR_SUCCESS;
+ int recursive_error = 0;
+ const char *protocol;
- send_all_header_fields(&h, r);
+ AP_DEBUG_ASSERT(!r->main);
- terminate_header(b2);
+ if (!ctx) {
+ ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
+ }
+ else if (ctx->headers_sent) {
+ /* Eat body if response must not have one. */
+ if (header_only) {
+ /* Still next filters may be waiting for EOS, so pass it (alone)
+ * when encountered and be done with this filter.
+ */
+ e = APR_BRIGADE_LAST(b);
+ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
+ APR_BUCKET_REMOVE(e);
+ apr_brigade_cleanup(b);
+ APR_BRIGADE_INSERT_HEAD(b, e);
+ ap_remove_output_filter(f);
+ rv = ap_pass_brigade(f->next, b);
+ }
+ apr_brigade_cleanup(b);
+ return rv;
+ }
+ }
- if (header_only) {
- e = APR_BRIGADE_LAST(b);
- if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
- APR_BUCKET_REMOVE(e);
- APR_BRIGADE_INSERT_TAIL(b2, e);
+ for (e = APR_BRIGADE_FIRST(b);
+ e != APR_BRIGADE_SENTINEL(b);
+ e = APR_BUCKET_NEXT(e))
+ {
+ if (AP_BUCKET_IS_ERROR(e) && !eb) {
+ eb = e->data;
+ continue;
+ }
+ /*
+ * If we see an EOC bucket it is a signal that we should get out
+ * of the way doing nothing.
+ */
+ if (AP_BUCKET_IS_EOC(e)) {
ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, b);
+ }
+ }
+
+ if (!ctx->headers_sent) {
+ merge_response_headers(r, &protocol);
+ if (!check_headers(r)) {
+ /* We may come back here from ap_die() below,
+ * so clear anything from this response.
+ */
+ apr_table_clear(r->headers_out);
+ apr_table_clear(r->err_headers_out);
+ r->content_type = r->content_encoding = NULL;
+ r->content_languages = NULL;
+ r->clength = r->chunked = 0;
+ apr_brigade_cleanup(b);
+
+ /* Don't recall ap_die() if we come back here (from its own internal
+ * redirect or error response), otherwise we can end up in infinite
+ * recursion; better fall through with 500, minimal headers and an
+ * empty body (EOS only).
+ */
+ if (!check_headers_recursion(r)) {
+ ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
+ return AP_FILTER_ERROR;
+ }
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ e = ap_bucket_eoc_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ e = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ ap_set_content_length(r, 0);
+ recursive_error = 1;
+ }
+ else if (eb) {
+ int status;
+ status = eb->status;
+ apr_brigade_cleanup(b);
+ ap_die(status, r);
+ return AP_FILTER_ERROR;
}
- apr_brigade_cleanup(b);
}
- rv = ap_pass_brigade(f->next, b2);
- apr_brigade_cleanup(b2);
- ctx->headers_sent = 1;
+ if (r->assbackwards) {
+ r->sent_bodyct = 1;
+ ap_remove_output_filter(f);
+ rv = ap_pass_brigade(f->next, b);
+ goto out;
+ }
+
+ if (!ctx->headers_sent) {
+ b2 = apr_brigade_create(r->pool, c->bucket_alloc);
+ basic_http_header(r, b2, protocol);
+
+ h.pool = r->pool;
+ h.bb = b2;
+
+ send_all_header_fields(&h, r);
+
+ terminate_header(b2);
+
+ if (header_only) {
+ e = APR_BRIGADE_LAST(b);
+ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(b2, e);
+ ap_remove_output_filter(f);
+ }
+ apr_brigade_cleanup(b);
+ }
+
+ rv = ap_pass_brigade(f->next, b2);
+ apr_brigade_cleanup(b2);
+ ctx->headers_sent = 1;
+ }
if (rv != APR_SUCCESS || header_only) {
goto out;

37
CVE-2024-43204.patch Normal file
View File

@@ -0,0 +1,37 @@
From b3d3ded288815bea063c3bf77dd80b26446f76ce Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:01:02 +0000
Subject: [PATCH] backport 1927032 from trunk
header only
Reviewed By: rpluem, jorton, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927040 13f79535-47bb-0310-9956-ffa450edef68
---
modules/metadata/mod_headers.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: httpd-2.4.51/modules/metadata/mod_headers.c
===================================================================
--- httpd-2.4.51.orig/modules/metadata/mod_headers.c
+++ httpd-2.4.51/modules/metadata/mod_headers.c
@@ -783,14 +783,14 @@ static int do_headers_fixup(request_rec
break;
case hdr_set:
if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
- ap_set_content_type_ex(r, process_tags(hdr, r), 1);
+ ap_set_content_type(r, process_tags(hdr, r));
}
apr_table_setn(headers, hdr->header, process_tags(hdr, r));
break;
case hdr_setifempty:
if (NULL == apr_table_get(headers, hdr->header)) {
if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
- ap_set_content_type_ex(r, process_tags(hdr, r), 1);
+ ap_set_content_type(r, process_tags(hdr, r));
}
apr_table_setn(headers, hdr->header, process_tags(hdr, r));
}

44
CVE-2024-47252.patch Normal file
View File

@@ -0,0 +1,44 @@
From c01e60707048be14a510f0a92128a5227923215c Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
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;
}

62
CVE-2025-23048.patch Normal file
View File

@@ -0,0 +1,62 @@
From c4cfa50c9068e8b8134c530ab21674e77d1278a2 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:04:49 +0000
Subject: [PATCH] backport 1927035 from trunk
update SNI validation
Reviewed By: rpluem, jorton, covener, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927043 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 9c510218441..d912a874dd9 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.<br />\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);

39
CVE-2025-49630.patch Normal file
View File

@@ -0,0 +1,39 @@
From 88304321841a2fe8bd5eacc70e69418b0b545ca5 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:05:49 +0000
Subject: [PATCH] backport 1927036 from trunk
tolerate missing host header in h2 proxy
Reviewed By: jorton, icing, rpluem
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927044 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http2/h2_proxy_session.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/modules/http2/h2_proxy_session.c b/modules/http2/h2_proxy_session.c
index d5d0f9bc6bc..2cfbb5f5d4b 100644
--- a/modules/http2/h2_proxy_session.c
+++ b/modules/http2/h2_proxy_session.c
@@ -850,6 +850,18 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url,
dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
if (dconf->preserve_host) {
authority = orig_host;
+ if (!authority) {
+ /* Duplicate mod_proxy behaviour if ProxyPreserveHost is
+ * used but an "HTTP/0.9" request is received without a
+ * Host: header */
+ authority = r->server->server_hostname;
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10511)
+ "HTTP/0.9 request (with no host line) "
+ "on incoming request and preserve host set "
+ "forcing hostname to be %s for uri %s",
+ authority, r->uri);
+ apr_table_setn(r->headers_in, "Host", authority);
+ }
}
else {
authority = puri.hostname;

198
CVE-2025-49812.patch Normal file
View File

@@ -0,0 +1,198 @@
From 87a7351c755c9ef8ab386e3090e44838c2a06d48 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
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 9af6f70fd03..d1f4fad8e23 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -741,11 +741,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 f9eca79e462..94cc2772e01 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;
}
@@ -2126,9 +2126,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 d912a874dd9..33aa1f71dc7 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 fb9edaa5eeb..794e51aa937 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -526,7 +526,6 @@ typedef enum {
SSL_ENABLED_UNSET = UNSET,
SSL_ENABLED_FALSE = 0,
SSL_ENABLED_TRUE = 1,
- SSL_ENABLED_OPTIONAL = 3
} ssl_enabled_t;
/**

496
CVE-2025-53020.patch Normal file
View File

@@ -0,0 +1,496 @@
From ef98f4f494ff2f99d736a3716cd31219688b46f5 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:12:49 +0000
Subject: [PATCH] backport 1927038 from trunk
improve h2 header error handling
Rewviewed By: icing, covener, rpluem
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927046 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http2/h2_request.c | 12 ++--
modules/http2/h2_request.h | 8 ++-
modules/http2/h2_session.c | 31 ++++++++-
modules/http2/h2_session.h | 3 +
modules/http2/h2_stream.c | 69 ++++++++++++-------
modules/http2/h2_util.c | 51 ++++++++------
modules/http2/h2_util.h | 11 ++-
test/modules/http2/test_200_header_invalid.py | 4 +-
8 files changed, 130 insertions(+), 59 deletions(-)
diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c
index 2713947c377..6373e0a244d 100644
--- a/modules/http2/h2_request.c
+++ b/modules/http2/h2_request.c
@@ -64,18 +64,20 @@ typedef struct {
apr_table_t *headers;
apr_pool_t *pool;
apr_status_t status;
+ h2_hd_scratch *scratch;
} h1_ctx;
static int set_h1_header(void *ctx, const char *key, const char *value)
{
h1_ctx *x = ctx;
int was_added;
- h2_req_add_header(x->headers, x->pool, key, strlen(key), value, strlen(value), 0, &was_added);
+ h2_req_add_header(x->headers, x->pool, key, strlen(key),
+ value, strlen(value), x->scratch, &was_added);
return 1;
}
apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
- request_rec *r)
+ request_rec *r, h2_hd_scratch *scratch)
{
h2_request *req;
const char *scheme, *authority, *path;
@@ -125,6 +127,7 @@ apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
x.pool = pool;
x.headers = req->headers;
x.status = APR_SUCCESS;
+ x.scratch = scratch;
apr_table_do(set_h1_header, &x, r->headers_in, NULL);
*preq = req;
@@ -134,7 +137,8 @@ apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ struct h2_hd_scratch *scratch,
+ int *pwas_added)
{
apr_status_t status = APR_SUCCESS;
@@ -185,7 +189,7 @@ apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
else {
/* non-pseudo header, add to table */
status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen,
- max_field_len, pwas_added);
+ scratch, pwas_added);
}
return status;
diff --git a/modules/http2/h2_request.h b/modules/http2/h2_request.h
index 7e20b697246..ae6b6a2510c 100644
--- a/modules/http2/h2_request.h
+++ b/modules/http2/h2_request.h
@@ -19,17 +19,21 @@
#include "h2.h"
+struct h2_hd_scratch;
+
h2_request *h2_request_create(int id, apr_pool_t *pool, const char *method,
const char *scheme, const char *authority,
const char *path, apr_table_t *header);
apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
- request_rec *r);
+ request_rec *r,
+ struct h2_hd_scratch *scratch);
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added);
+ struct h2_hd_scratch *scratch,
+ int *pwas_added);
apr_status_t h2_request_add_trailer(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c
index fc8b6119ae8..a5f1872bc20 100644
--- a/modules/http2/h2_session.c
+++ b/modules/http2/h2_session.c
@@ -109,13 +109,29 @@ static void cleanup_unprocessed_streams(h2_session *session)
h2_mplx_c1_streams_do(session->mplx, rst_unprocessed_stream, session);
}
+/* APR callback invoked if allocation fails. */
+static int abort_on_oom(int retcode)
+{
+ ap_abort_on_oom();
+ return retcode; /* unreachable, hopefully. */
+}
+
static h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
int initiated_on)
{
h2_stream * stream;
+ apr_allocator_t *allocator;
apr_pool_t *stream_pool;
+ apr_status_t rv;
- apr_pool_create(&stream_pool, session->pool);
+ rv = apr_allocator_create(&allocator);
+ if (rv != APR_SUCCESS)
+ return NULL;
+
+ apr_allocator_max_free_set(allocator, ap_max_mem_free);
+ apr_pool_create_ex(&stream_pool, session->pool, NULL, allocator);
+ apr_allocator_owner_set(allocator, stream_pool);
+ apr_pool_abort_set(abort_on_oom, stream_pool);
apr_pool_tag(stream_pool, "h2_stream");
stream = h2_stream_create(stream_id, stream_pool, session,
@@ -972,6 +988,14 @@ apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *
}
h2_c1_io_init(&session->io, session);
+ /* setup request header scratch buffers */
+ session->hd_scratch.max_len = session->s->limit_req_fieldsize?
+ session->s->limit_req_fieldsize : 8190;
+ session->hd_scratch.name =
+ apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
+ session->hd_scratch.value =
+ apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
+
session->padding_max = h2_config_sgeti(s, H2_CONF_PADDING_BITS);
if (session->padding_max) {
session->padding_max = (0x01 << session->padding_max) - 1;
@@ -1032,7 +1056,7 @@ apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *
n = h2_config_sgeti(s, H2_CONF_PUSH_DIARY_SIZE);
session->push_diary = h2_push_diary_create(session->pool, n);
-
+
if (APLOGcdebug(c)) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
H2_SSSN_LOG(APLOGNO(03200), session,
@@ -1699,9 +1723,10 @@ static void on_stream_state_enter(void *ctx, h2_stream *stream)
break;
case H2_SS_CLEANUP:
nghttp2_session_set_stream_user_data(session->ngh2, stream->id, NULL);
+ update_child_status(session, SERVER_BUSY_WRITE, "done", stream);
h2_mplx_c1_stream_cleanup(session->mplx, stream, &session->open_streams);
+ stream = NULL;
++session->streams_done;
- update_child_status(session, SERVER_BUSY_WRITE, "done", stream);
break;
default:
break;
diff --git a/modules/http2/h2_session.h b/modules/http2/h2_session.h
index 2c8f334cce0..7932a9e2ccf 100644
--- a/modules/http2/h2_session.h
+++ b/modules/http2/h2_session.h
@@ -29,6 +29,7 @@
*/
#include "h2.h"
+#include "h2_util.h"
struct apr_thread_mutext_t;
struct apr_thread_cond_t;
@@ -118,6 +119,8 @@ typedef struct h2_session {
struct h2_iqueue *out_c1_blocked; /* all streams with output blocked on c1 buffer full */
struct h2_iqueue *ready_to_process; /* all streams ready for processing */
+ h2_hd_scratch hd_scratch;
+
} h2_session;
const char *h2_session_state_str(h2_session_state state);
diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c
index 35b53860c03..f8214019404 100644
--- a/modules/http2/h2_stream.c
+++ b/modules/http2/h2_stream.c
@@ -659,7 +659,8 @@ apr_status_t h2_stream_set_request_rec(h2_stream *stream,
if (stream->rst_error) {
return APR_ECONNRESET;
}
- status = h2_request_rcreate(&req, stream->pool, r);
+ status = h2_request_rcreate(&req, stream->pool, r,
+ &stream->session->hd_scratch);
if (status == APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
H2_STRM_LOG(APLOGNO(03058), stream,
@@ -691,13 +692,11 @@ static void set_error_response(h2_stream *stream, int http_status)
static apr_status_t add_trailer(h2_stream *stream,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ h2_hd_scratch *scratch)
{
conn_rec *c = stream->session->c1;
- char *hname, *hvalue;
const char *existing;
- *pwas_added = 0;
if (nlen == 0 || name[0] == ':') {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EINVAL, c,
H2_STRM_LOG(APLOGNO(03060), stream,
@@ -710,20 +709,35 @@ static apr_status_t add_trailer(h2_stream *stream,
if (!stream->trailers_in) {
stream->trailers_in = apr_table_make(stream->pool, 5);
}
- hname = apr_pstrndup(stream->pool, name, nlen);
- h2_util_camel_case_header(hname, nlen);
- existing = apr_table_get(stream->trailers_in, hname);
- if (max_field_len
- && ((existing? strlen(existing)+2 : 0) + vlen + nlen + 2 > max_field_len)) {
- /* "key: (oldval, )?nval" is too long */
+
+ if (((nlen + vlen + 2) > scratch->max_len))
return APR_EINVAL;
+
+ /* We need 0-terminated strings to operate on apr_table */
+ AP_DEBUG_ASSERT(nlen < scratch->max_len);
+ memcpy(scratch->name, name, nlen);
+ scratch->name[nlen] = 0;
+ AP_DEBUG_ASSERT(vlen < scratch->max_len);
+ memcpy(scratch->value, value, vlen);
+ scratch->value[vlen] = 0;
+
+ existing = apr_table_get(stream->trailers_in, scratch->name);
+ if(existing) {
+ if (!vlen) /* not adding a 0-length value to existing */
+ return APR_SUCCESS;
+ if ((strlen(existing) + 2 + vlen + nlen + 2 > scratch->max_len)) {
+ /* "name: existing, value" is too long */
+ return APR_EINVAL;
+ }
+ apr_table_merge(stream->trailers_in, scratch->name, scratch->value);
}
- if (!existing) *pwas_added = 1;
- hvalue = apr_pstrndup(stream->pool, value, vlen);
- apr_table_mergen(stream->trailers_in, hname, hvalue);
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
- H2_STRM_MSG(stream, "added trailer '%s: %s'"), hname, hvalue);
-
+ else {
+ h2_util_camel_case_header(scratch->name, nlen);
+ apr_table_set(stream->trailers_in, scratch->name, scratch->value);
+ }
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ H2_STRM_MSG(stream, "added trailer '%s: %s'"),
+ scratch->name, scratch->value);
return APR_SUCCESS;
}
@@ -732,7 +746,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
const char *value, size_t vlen)
{
h2_session *session = stream->session;
- int error = 0, was_added = 0;
+ int error = 0;
apr_status_t status = APR_SUCCESS;
H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
@@ -760,6 +774,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
++stream->request_headers_added;
}
else if (H2_SS_IDLE == stream->state) {
+ int was_added;
if (!stream->rtmp) {
if (H2_STREAM_CLIENT_INITIATED(stream->id)) {
++stream->session->remote.emitted_count;
@@ -771,7 +786,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
}
status = h2_request_add_header(stream->rtmp, stream->pool,
name, nlen, value, vlen,
- session->s->limit_req_fieldsize, &was_added);
+ &session->hd_scratch, &was_added);
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c1,
H2_STRM_MSG(stream, "add_header: '%.*s: %.*s"),
(int)nlen, name, (int)vlen, value);
@@ -779,8 +794,8 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
}
else if (H2_SS_OPEN == stream->state) {
status = add_trailer(stream, name, nlen, value, vlen,
- session->s->limit_req_fieldsize, &was_added);
- if (was_added) ++stream->request_headers_added;
+ &session->hd_scratch);
+ if (!status) ++stream->request_headers_added;
}
else {
status = APR_EINVAL;
@@ -789,16 +804,17 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
if (APR_EINVAL == status) {
/* header too long */
- if (!h2_stream_is_ready(stream)) {
+ if (!h2_stream_is_ready(stream) && !stream->request_headers_failed) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
- H2_STRM_LOG(APLOGNO(10180), stream,"Request header exceeds "
- "LimitRequestFieldSize: %.*s"),
+ H2_STRM_LOG(APLOGNO(10180), stream,
+ "Request header exceeds LimitRequestFieldSize(%d): %.*s"),
+ (int)session->hd_scratch.max_len,
(int)H2MIN(nlen, 80), name);
}
error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
goto cleanup;
}
-
+
if (session->s->limit_req_fields > 0
&& stream->request_headers_added > session->s->limit_req_fields) {
/* too many header lines */
@@ -810,12 +826,13 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
if (!h2_stream_is_ready(stream)) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
H2_STRM_LOG(APLOGNO(10181), stream, "Number of request headers "
- "exceeds LimitRequestFields"));
+ "exceeds LimitRequestFields(%d)"),
+ (int)session->s->limit_req_fields);
}
error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
goto cleanup;
}
-
+
cleanup:
if (error) {
++stream->request_headers_failed;
diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
index 8e53cebdf92..605c348ca12 100644
--- a/modules/http2/h2_util.c
+++ b/modules/http2/h2_util.c
@@ -1693,10 +1693,9 @@ int h2_ignore_resp_trailer(const char *name, size_t len)
}
static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
- nghttp2_nv *nv, size_t max_field_len,
+ nghttp2_nv *nv, h2_hd_scratch *scratch,
int *pwas_added)
{
- char *hname, *hvalue;
const char *existing;
*pwas_added = 0;
@@ -1712,15 +1711,14 @@ static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
/* Cookie header come separately in HTTP/2, but need
* to be merged by "; " (instead of default ", ")
*/
- if (max_field_len
- && strlen(existing) + nv->valuelen + nv->namelen + 4
- > max_field_len) {
+ if ((strlen(existing) + nv->valuelen + nv->namelen + 4)
+ > scratch->max_len) {
/* "key: oldval, nval" is too long */
return APR_EINVAL;
}
- hvalue = apr_pstrndup(pool, (const char*)nv->value, nv->valuelen);
apr_table_setn(headers, "Cookie",
- apr_psprintf(pool, "%s; %s", existing, hvalue));
+ apr_psprintf(pool, "%s; %.*s", existing,
+ (int)nv->valuelen, nv->value));
return APR_SUCCESS;
}
}
@@ -1731,27 +1729,40 @@ static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
}
}
- hname = apr_pstrndup(pool, (const char*)nv->name, nv->namelen);
- h2_util_camel_case_header(hname, nv->namelen);
- existing = apr_table_get(headers, hname);
- if (max_field_len) {
- if ((existing? strlen(existing)+2 : 0) + nv->valuelen + nv->namelen + 2
- > max_field_len) {
- /* "key: (oldval, )?nval" is too long */
+ if (((nv->namelen + nv->valuelen + 2) > scratch->max_len))
+ return APR_EINVAL;
+
+ /* We need 0-terminated strings to operate on apr_table */
+ AP_DEBUG_ASSERT(nv->namelen < scratch->max_len);
+ memcpy(scratch->name, nv->name, nv->namelen);
+ scratch->name[nv->namelen] = 0;
+ AP_DEBUG_ASSERT(nv->valuelen < scratch->max_len);
+ memcpy(scratch->value, nv->value, nv->valuelen);
+ scratch->value[nv->valuelen] = 0;
+
+ *pwas_added = 1;
+ existing = apr_table_get(headers, scratch->name);
+ if (existing) {
+ if (!nv->valuelen) /* not adding a 0-length value to existing */
+ return APR_SUCCESS;
+ if ((strlen(existing) + 2 + nv->valuelen + nv->namelen + 2)
+ > scratch->max_len) {
+ /* "name: existing, value" is too long */
return APR_EINVAL;
}
+ apr_table_merge(headers, scratch->name, scratch->value);
+ }
+ else {
+ h2_util_camel_case_header(scratch->name, nv->namelen);
+ apr_table_set(headers, scratch->name, scratch->value);
}
- if (!existing) *pwas_added = 1;
- hvalue = apr_pstrndup(pool, (const char*)nv->value, nv->valuelen);
- apr_table_mergen(headers, hname, hvalue);
-
return APR_SUCCESS;
}
apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ h2_hd_scratch *scratch, int *pwas_added)
{
nghttp2_nv nv;
@@ -1759,7 +1770,7 @@ apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
nv.namelen = nlen;
nv.value = (uint8_t*)value;
nv.valuelen = vlen;
- return req_add_header(headers, pool, &nv, max_field_len, pwas_added);
+ return req_add_header(headers, pool, &nv, scratch, pwas_added);
}
/*******************************************************************************
diff --git a/modules/http2/h2_util.h b/modules/http2/h2_util.h
index d2e6548ba87..c2cab4afa45 100644
--- a/modules/http2/h2_util.h
+++ b/modules/http2/h2_util.h
@@ -397,14 +397,21 @@ apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
const struct h2_request *req);
#endif
+typedef struct h2_hd_scratch {
+ size_t max_len; /* header field size name + ': ' + value */
+ char *name; /* max_len+1 sized */
+ char *value; /* max_len+1 sized */
+
+} h2_hd_scratch;
+
/**
* Add a HTTP/2 header and return the table key if it really was added
* and not ignored.
*/
-apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
+apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added);
+ h2_hd_scratch *scratch, int *pwas_added);
/*******************************************************************************
* apr brigade helpers
diff --git a/test/modules/http2/test_200_header_invalid.py b/test/modules/http2/test_200_header_invalid.py
index 6b73301c282..1687e3d9818 100644
--- a/test/modules/http2/test_200_header_invalid.py
+++ b/test/modules/http2/test_200_header_invalid.py
@@ -133,7 +133,7 @@ def test_h2_200_11(self, env):
assert 431 == r.response["status"]
# test header field count, LimitRequestFields (default 100)
- # see #201: several headers with same name are mered and count only once
+ # see #201: several headers with same name are merged and counted
def test_h2_200_12(self, env):
url = env.mkurl("https", "cgi", "/")
opt = []
@@ -143,7 +143,7 @@ def test_h2_200_12(self, env):
r = env.curl_get(url, options=opt)
assert r.response["status"] == 200
r = env.curl_get(url, options=(opt + ["-H", "y: 2"]))
- assert r.response["status"] == 200
+ assert r.response["status"] == 431
# test header field count, LimitRequestFields (default 100)
# different header names count each

203
CVE-2025-55753.patch Normal file
View File

@@ -0,0 +1,203 @@
From ab9dd8e2cfe7d62efe5ff8925fbef1de756a2fc2 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <icing@apache.org>
Date: Thu, 20 Nov 2025 13:00:23 +0000
Subject: [PATCH] Merged /httpd/httpd/trunk:r1929514,1929883
Update mod_md to v2.6.6
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1929884 13f79535-47bb-0310-9956-ffa450edef68
---
STATUS | 8 --------
changes-entries/md_v2.6.5.txt | 9 +++++++++
changes-entries/md_v2.6.6.txt | 3 +++
docs/manual/mod/mod_md.xml | 17 +++++++++++++++++
modules/md/md_crypt.c | 10 +++++++---
modules/md/md_curl.c | 14 ++++++++------
modules/md/md_ocsp.c | 3 ++-
modules/md/md_version.h | 4 ++--
modules/md/mod_md_config.c | 21 +++++++++++++++++++++
modules/md/mod_md_config.h | 1 +
modules/md/mod_md_drive.c | 2 +-
11 files changed, 71 insertions(+), 21 deletions(-)
create mode 100644 changes-entries/md_v2.6.5.txt
create mode 100644 changes-entries/md_v2.6.6.txt
Index: httpd-2.4.63/changes-entries/md_v2.6.5.txt
===================================================================
--- /dev/null
+++ httpd-2.4.63/changes-entries/md_v2.6.5.txt
@@ -0,0 +1,9 @@
+ *) mod_md: update to version 2.6.5
+ - New directive `MDInitialDelay`, controlling how longer to wait after
+ a server restart before checking certificates for renewal.
+ [Michael Kaufmann]
+ - Hardening: when build with OpenSSL older than 1.0.2 or old libressl
+ versions, the parsing of ASN.1 time strings did not do a length check.
+ - Hardening: when reading back OCSP responses stored in the local JSON
+ store, missing 'valid' key led to uninitialized values, resulting in
+ wrong refresh behaviour.
Index: httpd-2.4.63/changes-entries/md_v2.6.6.txt
===================================================================
--- /dev/null
+++ httpd-2.4.63/changes-entries/md_v2.6.6.txt
@@ -0,0 +1,3 @@
+ *) mod_md: update to version 2.6.6
+ - Fix a small memory leak when using OpenSSL's BIGNUMs. [Theo Buehler]
+ - Fix reuse of curl easy handles by resetting them. [Michael Kaufmann]
Index: httpd-2.4.63/modules/md/md_crypt.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_crypt.c
+++ httpd-2.4.63/modules/md/md_crypt.c
@@ -198,7 +198,7 @@ static int pem_passwd(char *buf, int siz
/* Get the apr time (micro seconds, since 1970) from an ASN1 time, as stored in X509
* certificates. OpenSSL now has a utility function, but other *SSL derivatives have
- * not caughts up yet or chose to ignore. An alternative is implemented, we prefer
+ * not caught up yet or chose to ignore. An alternative is implemented, we prefer
* however the *SSL to maintain such things.
*/
static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
@@ -212,6 +212,10 @@ static apr_time_t md_asn1_time_get(const
const char* str = (const char*) time->data;
apr_size_t i = 0;
+ if ((time->length < 12) || (
+ (time->type == V_ASN1_GENERALIZEDTIME) && time->length < 16))
+ return 0;
+
memset(&t, 0, sizeof(t));
if (time->type == V_ASN1_UTCTIME) {/* two digit year */
@@ -1188,7 +1192,7 @@ const char *md_cert_get_serial_number(co
serial = BN_bn2hex(bn);
s = apr_pstrdup(p, serial);
OPENSSL_free((void*)serial);
- OPENSSL_free((void*)bn);
+ BN_free(bn);
}
return s;
}
Index: httpd-2.4.63/modules/md/md_curl.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_curl.c
+++ httpd-2.4.63/modules/md/md_curl.c
@@ -253,17 +253,19 @@ static apr_status_t internals_setup(md_h
rv = APR_EGENERAL;
goto leave;
}
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
- curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb);
- curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
}
else {
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "reusing curl instance from http");
+ curl_easy_reset(curl);
}
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb);
+ curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
+
internals = apr_pcalloc(req->pool, sizeof(*internals));
internals->curl = curl;
Index: httpd-2.4.63/modules/md/md_ocsp.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_ocsp.c
+++ httpd-2.4.63/modules/md/md_ocsp.c
@@ -190,6 +190,7 @@ static apr_status_t ostat_from_json(md_o
md_timeperiod_t valid;
apr_status_t rv = APR_ENOENT;
+ memset(&valid, 0, sizeof(valid));
memset(resp_der, 0, sizeof(*resp_der));
memset(resp_valid, 0, sizeof(*resp_valid));
s = md_json_dups(p, json, MD_KEY_VALID, MD_KEY_FROM, NULL);
@@ -531,7 +532,7 @@ static const char *certid_summary(const
bn = ASN1_INTEGER_to_BN(aserial, NULL);
s = BN_bn2hex(bn);
serial = apr_pstrdup(p, s);
- OPENSSL_free((void*)bn);
+ BN_free(bn);
OPENSSL_free((void*)s);
}
return apr_psprintf(p, "certid[der=%s, issuer=%s, key=%s, serial=%s]",
Index: httpd-2.4.63/modules/md/mod_md_config.c
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_config.c
+++ httpd-2.4.63/modules/md/mod_md_config.c
@@ -84,6 +84,7 @@ static md_mod_conf_t defmc = {
"crt.sh", /* default cert checker site name */
"https://crt.sh?q=", /* default cert checker site url */
NULL, /* CA cert file to use */
+ APR_TIME_C(0), /* initial cert check delay */
apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */
apr_time_from_sec(5), /* minimum delay for retries */
13, /* retry_failover after 14 errors, with 5s delay ~ half a day */
@@ -625,6 +626,24 @@ static const char *md_config_set_base_se
return set_on_off(&config->mc->manage_base_server, value, cmd->pool);
}
+static const char *md_config_set_initial_delay(cmd_parms *cmd, void *dc, const char *value)
+{
+ md_srv_conf_t *config = md_config_get(cmd->server);
+ const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
+ apr_time_t delay;
+
+ (void)dc;
+ if (err) return err;
+ if (md_duration_parse(&delay, value, "s") != APR_SUCCESS) {
+ return "unrecognized duration format";
+ }
+ if (delay < 0) {
+ return "initial delay must not be negative";
+ }
+ config->mc->initial_delay = delay;
+ return NULL;
+}
+
static const char *md_config_set_check_interval(cmd_parms *cmd, void *dc, const char *value)
{
md_srv_conf_t *config = md_config_get(cmd->server);
@@ -1323,6 +1342,8 @@ const command_rec md_cmds[] = {
"Configure locking of store for updates."),
AP_INIT_TAKE1("MDMatchNames", md_config_set_match_mode, NULL, RSRC_CONF,
"Determines how DNS names are matched to vhosts."),
+ AP_INIT_TAKE1("MDInitialDelay", md_config_set_initial_delay, NULL, RSRC_CONF,
+ "How long to delay the first certificate check."),
AP_INIT_TAKE1("MDCheckInterval", md_config_set_check_interval, NULL, RSRC_CONF,
"Time between certificate checks."),
AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
Index: httpd-2.4.63/modules/md/mod_md_config.h
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_config.h
+++ httpd-2.4.63/modules/md/mod_md_config.h
@@ -75,6 +75,7 @@ struct md_mod_conf_t {
const char *cert_check_name; /* name of the linked certificate check site */
const char *cert_check_url; /* url "template for" checking a certificate */
const char *ca_certs; /* root certificates to use for connections */
+ apr_time_t initial_delay; /* how long to delay the first cert renewal check */
apr_time_t check_interval; /* duration between cert renewal checks */
apr_time_t min_delay; /* minimum delay for retries */
int retry_failover; /* number of errors to trigger CA failover */
Index: httpd-2.4.63/modules/md/mod_md_drive.c
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_drive.c
+++ httpd-2.4.63/modules/md/mod_md_drive.c
@@ -346,7 +346,7 @@ apr_status_t md_renew_start_watching(md_
"create md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
return rv;
}
- rv = wd_register_callback(dctx->watchdog, 0, dctx, run_watchdog);
+ rv = wd_register_callback(dctx->watchdog, mc->initial_delay, dctx, run_watchdog);
ap_log_error(APLOG_MARK, rv? APLOG_CRIT : APLOG_DEBUG, rv, s, APLOGNO(10067)
"register md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
return rv;

35
CVE-2025-58098.patch Normal file
View File

@@ -0,0 +1,35 @@
From ecc1b8f3817e3dcab9c1f24f905752d3c0a279af Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:00:14 +0000
Subject: [PATCH] don't pass args for SSI request
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930161 13f79535-47bb-0310-9956-ffa450edef68
---
modules/generators/mod_cgid.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c
index b27dd802d80..94ad7ee8733 100644
--- a/modules/generators/mod_cgid.c
+++ b/modules/generators/mod_cgid.c
@@ -239,7 +239,7 @@ static char **create_argv(apr_pool_t *p, char *path, char *user, char *group,
char *w;
int idx = 0;
- if (!(*args) || ap_strchr_c(args, '=')) {
+ if (!args || !(*args) || ap_strchr_c(args, '=')) {
numwords = 0;
}
else {
@@ -932,7 +932,10 @@ static int cgid_server(void *data)
apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans);
}
- argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args);
+ /* Do not pass args in case of SSI requests */
+ argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL,
+ argv0,
+ cgid_req.req_type == SSI_REQ ? NULL : r->args);
/* We want to close sd2 for the new CGI process too.
* If it is left open it'll make ap_pass_brigade() block

63
CVE-2025-65082.patch Normal file
View File

@@ -0,0 +1,63 @@
From e4f00c5eb71d8a7aa1f52b5279832986f669d463 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:03:12 +0000
Subject: [PATCH] envvars from HTTP headers low precedence
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930163 13f79535-47bb-0310-9956-ffa450edef68
---
server/util_script.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/server/util_script.c b/server/util_script.c
index 72175e75824..6a18aec8c90 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -126,6 +126,8 @@ AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
}
}
for (i = 0; i < env_arr->nelts; ++i) {
+ int changed = 0;
+
if (!elts[i].key) {
continue;
}
@@ -133,18 +135,36 @@ AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
whack = env[j];
if (apr_isdigit(*whack)) {
*whack++ = '_';
+ changed = 1;
}
while (*whack != '=') {
#ifdef WIN32
- if (!apr_isalnum(*whack) && *whack != '(' && *whack != ')') {
+ if (!apr_isalnum(*whack) && *whack != '_' && *whack != '(' && *whack != ')') {
#else
- if (!apr_isalnum(*whack)) {
+ if (!apr_isalnum(*whack) && *whack != '_') {
#endif
*whack = '_';
+ changed = 1;
}
++whack;
}
- ++j;
+ if (changed) {
+ *whack = '\0';
+ /*
+ * If after cleaning up the key the key is identical to an existing key
+ * in the table drop this environment variable. This also prevents
+ * to override CGI reserved environment variables with variables whose
+ * names have an invalid character instead of '_', but are otherwise
+ * equal to the names CGI reserved environment variables.
+ */
+ if (!apr_table_get(t, env[j])) {
+ ++j;
+ *whack = '=';
+ }
+ }
+ else {
+ ++j;
+ }
}
env[j] = NULL;

39
CVE-2025-66200.patch Normal file
View File

@@ -0,0 +1,39 @@
From 9d26b95787b229a3f6195d7beead774d131eeda1 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:04:29 +0000
Subject: [PATCH] don't use request notes for suexec
also, stop accepting the obscure "note" option in
RequestHeader, it is only documented/described as being
meant for Header (output filter).
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930164 13f79535-47bb-0310-9956-ffa450edef68
---
modules/mappers/mod_userdir.c | 4 ++--
modules/metadata/mod_headers.c | 6 +++++-
2 files changed, 7 insertions(+), 3 deletions(-)
Index: httpd-2.4.63/modules/mappers/mod_userdir.c
===================================================================
--- httpd-2.4.63.orig/modules/mappers/mod_userdir.c
+++ httpd-2.4.63/modules/mappers/mod_userdir.c
@@ -334,7 +334,7 @@ static int translate_userdir(request_rec
r->finfo = statbuf;
/* For use in the get_suexec_identity phase */
- apr_table_setn(r->notes, "mod_userdir_user", user);
+ ap_set_module_config(r->request_config, &userdir_module, (void *)user);
return OK;
}
@@ -348,7 +348,7 @@ static ap_unix_identity_t *get_suexec_id
{
ap_unix_identity_t *ugid = NULL;
#if APR_HAS_USER
- const char *username = apr_table_get(r->notes, "mod_userdir_user");
+ const char *username = (const char*) ap_get_module_config(r->request_config, &userdir_module);
if (username == NULL) {
return NULL;

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 1996, 1997, 1998 S.u.S.E. GmbH
# Copyright (c) 1998, 1999, 2000, 2001 SuSE GmbH

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#
# spec file for package apache2
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%global upstream_name httpd
%global testsuite_name %{upstream_name}-framework
%global tversion svn1901574
%global tversion svn1921782
%global flavor @BUILD_FLAVOR@%{nil}
%define mpm %{nil}
%if "%{flavor}" == "prefork" || "%{flavor}" == "test_prefork"
@@ -107,7 +107,7 @@
%define build_http2 1
Name: apache2%{psuffix}
Version: 2.4.62
Version: 2.4.63
Release: 0
Summary: The Apache HTTPD Server
License: Apache-2.0
@@ -181,6 +181,21 @@ Patch2: apache2-logresolve-tmp-security.patch
Patch3: apache2-LimitRequestFieldSize-limits-headers.patch
# [fate317766] backport of an upstream commit
Patch4: apache2-HttpContentLengthHeadZero-HttpExpectStrict.patch
# FIX-UPSTREAM: bsc#1246477 CVE-2024-42516: HTTP response splitting
Patch5: CVE-2024-42516.patch
# FIX-UPSTREAM: bsc#1246305 CVE-2024-43204: SSRF when mod_proxy is loaded allows an attacker to send outbound proxy requests to a URL controlled by them
Patch6: CVE-2024-43204.patch
# FIX-UPSTREAM: bsc#1246303 CVE-2024-47252: insufficient escaping of user-supplied data in mod_ssl allows an untrusted SSL/TLS client to insert escape characters into log files
Patch7: CVE-2024-47252.patch
# FIX-UPSTREAM: bsc#1246302 CVE-2025-23048: access control bypass by trusted clients through TLS 1.3 session resumption in some mod_ssl configurations
Patch8: CVE-2025-23048.patch
# FIX-UPSTREAM: bsc#1246307 CVE-2025-49630: denial of service can be triggered by untrusted clients causing an assertion in mod_proxy_http2
Patch9: CVE-2025-49630.patch
# FIX-UPSTREAM: bsc#1246169 CVE-2025-49812: Opossum Attack Application Layer Desynchronization using Opportunistic TLS
Patch10: CVE-2025-49812.patch
# FIX-UPSTREAM: bsc#1246306 CVE-2025-53020: HTTP/2 denial of service due to late release of memory after effective lifetime
Patch11: CVE-2025-53020.patch
# PATCH: https://marc.info/?l=apache-httpd-users&m=147448312531134&w=2
Patch100: apache-test-application-xml-type.patch
# PATCH: /test_ssl_var_lookup?SSL_SERVER_SAN_DNS_0 returns <build-host-name>
@@ -190,6 +205,15 @@ Patch100: apache-test-application-xml-type.patch
# even if in live system I do not experience this inconsistency, let's turn off
# these variables from the test
Patch101: apache-test-turn-off-variables-in-ssl-var-lookup.patch
#FIX-UPSTREAM: bsc#1254511 CVE-2025-55753
Patch102: CVE-2025-55753.patch
#FIX-UPSTREAM: bsc#1254512 CVE-2025-58098
Patch103: CVE-2025-58098.patch
#FIX-UPSTREAM: bsc#1254514 CVE-2025-65082
Patch104: CVE-2025-65082.patch
#FIX-UPSTREAM: bsc#1254515 CVE-2025-66200
Patch105: CVE-2025-66200.patch
BuildRequires: apache-rpm-macros-control
#Since 2.4.7 the event MPM requires apr 1.5.0 or later.
BuildRequires: apr-devel >= 1.5.0
@@ -262,6 +286,7 @@ BuildRequires: netcfg
# /SECTION
%if "%{mpm}" != ""
Provides: apache2-MPM
Requires: apache2
%endif
%if "%{flavor}" == ""
Requires: %{_sysconfdir}/mime.types
@@ -549,6 +574,8 @@ mkdir -p %{buildroot}%{_sysconfdir}/apache2/sysconfig.d
mkdir -p %{buildroot}/%{_fillupdir}
install -m 644 %{SOURCE30} %{buildroot}%{_fillupdir}/sysconfig.apache2
# htdocsdir is used by default-server.conf
mkdir -p %{buildroot}%{htdocsdir}
mkdir -p %{buildroot}%{sysconfdir}
mkdir -p %{buildroot}%{sysconfdir}/conf.d
for c in default-server.conf \
@@ -733,6 +760,8 @@ apxs -q CFLAGS | grep "\\%{optflags}"
cp %{SOURCE21} mod_example.c
apxs -c mod_example.c
test_dir="$PWD/my-test-devel"
# hack: %{_libdir} cannot be used in noarch packages, define shell variable _libdir, using apxs to find the real value
_libexecdir=$(apxs -q libdir)/apache2
echo "Try to load example module"
mkdir $test_dir
cat > $test_dir/httpd.conf << EOF
@@ -743,7 +772,7 @@ User $(id -un)
Group $(id -gn)
Listen 60080
DocumentRoot $test_dir
LoadModule authz_core_module %{libexecdir}-%{default_mpm}/mod_authz_core.so
LoadModule authz_core_module ${_libexecdir}-%{default_mpm}/mod_authz_core.so
LoadModule example_module $PWD/.libs/mod_example.so
<Location /hello>
SetHandler example-handler
@@ -778,15 +807,17 @@ function dep()
}
# create a conf loading all MPM's modules
echo > $PWD/load-all-modules.conf
# hack: %{_libdir} cannot be used in noarch packages, define shell variable _libdir, using apxs to find the real value
_libdir=$(apxs -q libdir)
# hack: sort -u to load mod_proxy before mod_proxy_http, mod_cache before mod_cache_disk, etc.
modules=$(find %{_libdir}/apache2-%{mpm}/ %{_libdir}/apache2/ -name *.so | sed 's:.*/mod_\(.*\).so:\1:' | sort -u)
modules=$(find ${_libdir}/apache2-%{mpm}/ ${_libdir}/apache2/ -name *.so | sed 's:.*/mod_\(.*\).so:\1:' | sort -u)
# fix up dependencies
dep "lbmethod_bybusyness" "proxy"
dep "lbmethod_byrequests" "proxy"
dep "lbmethod_bytraffic" "proxy"
dep "lbmethod_heartbeat" "proxy"
for m in $modules; do
path=$(find %{_libdir}/apache2-%{mpm}/ %{_libdir}/apache2/ -name mod_$m.so | head -n 1)
path=$(find ${_libdir}/apache2-%{mpm}/ ${_libdir}/apache2/ -name mod_$m.so | head -n 1)
if ! grep -q "mod_$m.c" $PWD/load-all-modules.conf; then
echo "<IfModule !mod_$m.c>" >> $PWD/load-all-modules.conf
echo " LoadModule ${m}_module $path" >> $PWD/load-all-modules.conf
@@ -834,6 +865,8 @@ exit 0
%attr(750,root,root) %dir %{logfiledir}
%attr(750,%{httpduser},root) %dir %{proxycachedir}
%attr(750,%{httpduser},root) %dir %{localstatedir}
%dir %{datadir}
%dir %{htdocsdir}
%dir %{libexecdir}
%dir %{_libexecdir}
%attr(755,root,root) %{_libexecdir}/apache2_MMN

Binary file not shown.

View File

@@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZbLUT+dL1ePeOsPwgngd5G1ZVPoFAmaVEjgACgkQgngd5G1Z
VPqlUA//dMZ01CalmRf4Li2gDH+ETlQXkMST+2IYNCWZzV78g5wfjpZtApKOk+6O
73WxdNSvnB15CJVIi/wXN/8ZQHu3u9kHCHw+ydDhOq7CiSAe1x5k0PcodR+me299
PErBiAaBct+oJOnPCRdw5c5g3jomZgg1Nt5xS5NmI83UnbT9KHd92nNFdIjp6nFE
mKzsQSWSSXkObj83inJ3HvT8ALGr5TpMjHSJAC/YP9B9FuTW4lQh0XFEESz6LcR/
Z8GWAV0qfauRhNYcp5qYcVdreVAk0J9vfnruv9OdYsMI/sDM2PYAyDk9pCMuVIfv
PuZd8n/EpMuQfeWBOLzkft2TjNYx0UAt0xLK0/FLQqbZSKgCxce3mnbm0N3qXl8h
OpWYC86h4y4shaBOCAHI4oqRFbIlbf9bssMRSYfBYTJ1k8zmADWAhIsr5276A33G
S8Z+Ah1XeYkvy1blSJDRqECAPLtAXgesLadpkTKTwu+9BmHXYllSmfdhW8D3v6SA
Ab7RMonp7poBexO0o0mm14cEAwetffUhSrFfvGp7sTBjQYH3s309HtRBuLJOwmP2
uZvAKo84nJVaZIe7TTjpA/om7sq08Jq8xdzGbEhfGnOrtg/34d3K5S9tDvBMkmDq
HfYjFxCmfTbUDy4nqVNZcwno6jApweon+KAHbG/vJ2uMWozn2Bo=
=Lelg
-----END PGP SIGNATURE-----

BIN
httpd-2.4.63.tar.bz2 LFS Normal file

Binary file not shown.

16
httpd-2.4.63.tar.bz2.asc Normal file
View File

@@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEqT1i7MPI6hLbIg7JNOp25nkUhagFAmeOpZMACgkQNOp25nkU
hajzCg/+I/j8u/tCFeaQAf5ZKyGZ8Kcpxf+/lP4Kr79emBwdROZFGP+ipfuyRpax
A8/WXTeVs6bWmg5edPIQAC1mDpj7rx2Pwa7xKV+/3/npQMPV4cqgbZfzgQD2NnoD
8Qs6pkjwF6ygn+4y/KQLF5MIh4G0lIkx/ddt+lHbt2FkJXT5JV1cyJ+kKrTLJdlB
RDMXcF2XleFFzApf9VCYWFPTlgmxAe4FG65JMwxh3WJeiX0vrLH+GnOyAXHotBOs
NbXQKQD5cM6/JzA3F4Jni/2co9Wsjg+zENx3hIjxJZvVtXRIC4BpmAJOeQIyoNwo
VVwe3Uo9Cz+ZFTYMecwnR/B5tm4IkQ0K9MXRK/jxxKds4CF/bnt0BClaSRqXrJJW
hwciu0Yw9nsCCQbz+vwMKVMRtQ1m2/Cl3+9K/9RYwdgfTQmNYcu3J+19trvRx2Vf
OVtwFNm2tps2YtOV1NAnr2huHt257WVis9ElCOwIpUqwJZvzLCG2VaSq0vlYZqP8
iQoQA25f9Ln34KdpF7BU2PO9LraFJNTHFIed3cd8L7U14H9iQ93mSUlibzY3HvK4
B3qeXmsn3YpJpgsvhOUPR7mTlhOsPSIdRW0vuLOrN5Rz3uVWRG8vpjCeZCYSYWBf
4KzbwEZ6n9dfc2D5N6Yx3uTdmKhAg1O1ryk7E6Sp+pVybFQrzsc=
=ttO/
-----END PGP SIGNATURE-----

Binary file not shown.

Binary file not shown.