1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
Description: Fix CVE-2025-54571
Author: Ervin Hegedüs <airween@gmail.com>
Last-Update: 2025-08-07
--- a/apache2/apache2_io.c
+++ b/apache2/apache2_io.c
@@ -192,27 +192,29 @@
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 @@
* 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 @@
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 @@
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 @@
*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 @@
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 @@
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 @@
} 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 @@
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;
}
--- a/apache2/mod_security2.c
+++ b/apache2/mod_security2.c
@@ -1032,56 +1032,15 @@
}
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
|