diff --git a/backport-CVE-2025-54571.patch b/backport-CVE-2025-54571.patch new file mode 100644 index 0000000000000000000000000000000000000000..dd9a9929d8f59e91ac8ca495d7b330e686fe5e0a --- /dev/null +++ b/backport-CVE-2025-54571.patch @@ -0,0 +1,222 @@ +From dfbde557acc41d858dbe04d4b6eaec64478347ff Mon Sep 17 00:00:00 2001 +From: Ervin Hegedus +Date: Wed, 30 Jul 2025 10:55:33 +0200 +Subject: [PATCH] Fix invalid request handling + +--- + apache2/apache2_io.c | 48 +++++++++++++++++----------------- + apache2/mod_security2.c | 57 ++++++----------------------------------- + 2 files changed, 32 insertions(+), 73 deletions(-) + +diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c +index 405b649ae4..8deeb01c9a 100644 +--- a/apache2/apache2_io.c ++++ b/apache2/apache2_io.c +@@ -192,27 +192,29 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + if (msr->txcfg->debuglog_level >= 4) { + msr_log(msr, 4, "Input filter: This request does not have a body."); + } +- return 0; ++ return APR_SUCCESS; + } + + if (msr->txcfg->reqbody_access != 1) { + if (msr->txcfg->debuglog_level >= 4) { + msr_log(msr, 4, "Input filter: Request body access not enabled."); + } +- return 0; ++ return APR_SUCCESS; + } + + if (msr->txcfg->debuglog_level >= 4) { + msr_log(msr, 4, "Input filter: Reading request body."); + } + if (modsecurity_request_body_start(msr, error_msg) < 0) { +- return -1; ++ return HTTP_INTERNAL_SERVER_ERROR; + } + + finished_reading = 0; + msr->if_seen_eos = 0; + bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc); +- if (bb_in == NULL) return -1; ++ if (bb_in == NULL) { ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } + do { + apr_status_t rc; + +@@ -222,25 +224,17 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + * too large and APR_EGENERAL when the client disconnects. + */ + switch(rc) { +- case APR_INCOMPLETE : +- *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc)); +- return -7; +- case APR_EOF : +- *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc)); +- return -6; +- case APR_TIMEUP : +- *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc)); +- return -4; + case AP_FILTER_ERROR : + *error_msg = apr_psprintf(msr->mp, "Error reading request body: HTTP Error 413 - Request entity too large. (Most likely.)"); +- return -3; ++ break; + case APR_EGENERAL : + *error_msg = apr_psprintf(msr->mp, "Error reading request body: Client went away."); +- return -2; ++ break; + default : + *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc)); +- return -1; ++ break; + } ++ return ap_map_http_request_error(rc, HTTP_BAD_REQUEST); + } + + /* Loop through the buckets in the brigade in order +@@ -256,7 +250,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + rc = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ); + if (rc != APR_SUCCESS) { + *error_msg = apr_psprintf(msr->mp, "Failed reading input / bucket (%d): %s", rc, get_apr_error(msr->mp, rc)); +- return -1; ++ return HTTP_INTERNAL_SERVER_ERROR; + } + + if (msr->txcfg->debuglog_level >= 9) { +@@ -269,7 +263,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) { + *error_msg = apr_psprintf(msr->mp, "Request body is larger than the " + "configured limit (%ld).", msr->txcfg->reqbody_limit); +- return -5; ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; + } else if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) { + + *error_msg = apr_psprintf(msr->mp, "Request body is larger than the " +@@ -290,7 +284,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + *error_msg = apr_psprintf(msr->mp, "Request body is larger than the " + "configured limit (%ld).", msr->txcfg->reqbody_limit); + +- return -5; ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + } + +@@ -300,7 +294,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + modsecurity_request_body_to_stream(msr, buf, buflen, error_msg); + #else + if (modsecurity_request_body_to_stream(msr, buf, buflen, error_msg) < 0) { +- return -1; ++ return HTTP_INTERNAL_SERVER_ERROR; + } + #endif + } +@@ -319,7 +313,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) { + *error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the " + "configured limit (%ld).", msr->txcfg->reqbody_no_files_limit); +- return -5; ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; + } else if ((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) { + *error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the " + "configured limit (%ld).", msr->txcfg->reqbody_no_files_limit); +@@ -329,12 +323,12 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + } else { + *error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the " + "configured limit (%ld).", msr->txcfg->reqbody_no_files_limit); +- return -5; ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; + } + } + + if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) +- return -1; ++ return HTTP_INTERNAL_SERVER_ERROR; + } + + } +@@ -357,7 +351,13 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { + + msr->if_status = IF_STATUS_WANTS_TO_RUN; + +- return rcbe; ++ if (rcbe == -5) { ++ return HTTP_REQUEST_ENTITY_TOO_LARGE; ++ } ++ if (rcbe < 0) { ++ return HTTP_INTERNAL_SERVER_ERROR; ++ } ++ return APR_SUCCESS; + } + + +diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c +index 0dcb6b3e75..97c49646bc 100644 +--- a/apache2/mod_security2.c ++++ b/apache2/mod_security2.c +@@ -1032,56 +1032,15 @@ static int hook_request_late(request_rec *r) { + } + + rc = read_request_body(msr, &my_error_msg); +- if (rc < 0 && msr->txcfg->is_enabled == MODSEC_ENABLED) { +- switch(rc) { +- case -1 : +- if (my_error_msg != NULL) { +- msr_log(msr, 1, "%s", my_error_msg); +- } +- return HTTP_INTERNAL_SERVER_ERROR; +- break; +- case -4 : /* Timeout. */ +- if (my_error_msg != NULL) { +- msr_log(msr, 4, "%s", my_error_msg); +- } +- r->connection->keepalive = AP_CONN_CLOSE; +- return HTTP_REQUEST_TIME_OUT; +- break; +- case -5 : /* Request body limit reached. */ +- msr->inbound_error = 1; +- if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) { +- r->connection->keepalive = AP_CONN_CLOSE; +- if (my_error_msg != NULL) { +- msr_log(msr, 1, "%s. Deny with code (%d)", my_error_msg, HTTP_REQUEST_ENTITY_TOO_LARGE); +- } +- return HTTP_REQUEST_ENTITY_TOO_LARGE; +- } else { +- if (my_error_msg != NULL) { +- msr_log(msr, 1, "%s", my_error_msg); +- } +- } +- break; +- case -6 : /* EOF when reading request body. */ +- if (my_error_msg != NULL) { +- msr_log(msr, 4, "%s", my_error_msg); +- } +- r->connection->keepalive = AP_CONN_CLOSE; +- return HTTP_BAD_REQUEST; +- break; +- case -7 : /* Partial recieved */ +- if (my_error_msg != NULL) { +- msr_log(msr, 4, "%s", my_error_msg); +- } +- r->connection->keepalive = AP_CONN_CLOSE; +- return HTTP_BAD_REQUEST; +- break; +- default : +- /* allow through */ +- break; ++ if (rc != OK) { ++ if (my_error_msg != NULL) { ++ msr_log(msr, 1, "%s", my_error_msg); + } +- +- msr->msc_reqbody_error = 1; +- msr->msc_reqbody_error_msg = my_error_msg; ++ if (rc == HTTP_REQUEST_ENTITY_TOO_LARGE) { ++ msr->inbound_error = 1; ++ } ++ r->connection->keepalive = AP_CONN_CLOSE; ++ return rc; + } + + /* Update the request headers. They might have changed after diff --git a/mod_security.spec b/mod_security.spec index acab799a4b139f08107e6eaa689249e196a701ac..b9e86eb6f7d39b065ce843d43e99abda9d8ceaad 100644 --- a/mod_security.spec +++ b/mod_security.spec @@ -7,7 +7,7 @@ Name: mod_security Version: 2.9.11 -Release: 1 +Release: 2 Summary: Security module for the Apache HTTP Server License: Apache-2.0 URL: https://www.modsecurity.org/ @@ -17,6 +17,7 @@ Source2: 10-mod_security.conf Source3: modsecurity_localrules.conf Patch0001: modsecurity-2.9.3-apulibs.patch Patch0002: mod_security-2.9.8-remote-rules-timeout.patch +Patch0003: backport-CVE-2025-54571.patch Requires: httpd httpd-mmn = %{_httpd_mmn} BuildRequires: gcc make perl-generators httpd-devel yajl yajl-devel pcre2-devel @@ -106,6 +107,9 @@ install -m0755 mlogc/mlogc-batch-load.pl %{buildroot}%{_bindir}/mlogc-batch-load %endif %changelog +* Thu Aug 07 2025 yujingbo - 2.9.11-2 +- Fix CVE-2025-54571 + * Fri Jul 04 2025 wangkai <13474090681@163.com> - 2.9.11-1 - Update to 2.9.11 for fix CVE-2025-52891