File apache2-mod_security2-CVE-2025-54571.patch of Package apache2-mod_security2.40324

From dfbde557acc41d858dbe04d4b6eaec64478347ff Mon Sep 17 00:00:00 2001
From: Ervin Hegedus <airween@gmail.com>
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(-)

Index: modsecurity-2.9.4/apache2/apache2_io.c
===================================================================
--- modsecurity-2.9.4.orig/apache2/apache2_io.c
+++ modsecurity-2.9.4/apache2/apache2_io.c
@@ -187,27 +187,29 @@ apr_status_t read_request_body(modsec_re
         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;
 
@@ -219,27 +221,19 @@ apr_status_t read_request_body(modsec_re
             switch(rc) {
                 case AP_FILTER_ERROR :
                     *error_msg = apr_pstrdup(msr->mp, "Error reading request body: filter error");
-                    return -8;
+                    break;
 
-                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 APR_ENOSPC:
                     *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
@@ -255,7 +249,7 @@ apr_status_t read_request_body(modsec_re
             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) {
@@ -268,7 +262,7 @@ apr_status_t read_request_body(modsec_re
                 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 "
@@ -289,7 +283,7 @@ apr_status_t read_request_body(modsec_re
                     *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;
                 }
             }
 
@@ -299,7 +293,7 @@ apr_status_t read_request_body(modsec_re
                 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
             }
@@ -318,7 +312,7 @@ apr_status_t read_request_body(modsec_re
                         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);
@@ -328,12 +322,12 @@ apr_status_t read_request_body(modsec_re
                         } 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;
                 }
 
             }
@@ -356,7 +350,13 @@ apr_status_t read_request_body(modsec_re
 
     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;
 }
 
 
Index: modsecurity-2.9.4/apache2/mod_security2.c
===================================================================
--- modsecurity-2.9.4.orig/apache2/mod_security2.c
+++ modsecurity-2.9.4/apache2/mod_security2.c
@@ -1013,64 +1013,18 @@ static int hook_request_late(request_rec
     }
 
     rc = read_request_body(msr, &my_error_msg);
-    if (rc < 0) {
-        switch(rc) {
-            case -1 :
-                if (my_error_msg != NULL) {
-                    msr_log(msr, 1, "%s", my_error_msg);
-                }
-                return HTTP_INTERNAL_SERVER_ERROR;
-                break;
-            case -2 : /* Bad request. */
-            case -6 : /* EOF when reading request body. */
-            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;
-            case -3 : /* Apache's LimitRequestBody. */
-                if (my_error_msg != NULL) {
-                    msr_log(msr, 1, "%s", my_error_msg);
-                }
-                return HTTP_REQUEST_ENTITY_TOO_LARGE;
-                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 -8 : /* Filter error. */
-                if (my_error_msg != NULL) {
-                    msr_log(msr, 1, "%s", my_error_msg);
-                }
-                return AP_FILTER_ERROR;
-                break;
-            default :
-                /* allow through */
-                break;
-        }
 
-        msr->msc_reqbody_error = 1;
-        msr->msc_reqbody_error_msg = my_error_msg;
-    }
+    if (rc != OK) {
+        if (my_error_msg != NULL) {
+            msr_log(msr, 1, "%s", 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
      * the body was read (trailers).
openSUSE Build Service is sponsored by