Hi list,
I discovered that a misconfigured mod_rewrite rule could cause the apache web
server (2.2.23 and 2.4.3) to fall into an infinite loop and eat all of the
available memory, until killed by the OOM killer:
Put the following lines in .htaccess file:
RewriteEngine On
RewriteRule .* a [N]
Then try to access http://<domain>/something. The result is:
www-data 50554 99.7 14.6 3109060 613756 ?? R 12:56PM 0:07.55
/usr/local/apache/bin/httpd -k restart
I thought that this scenario was limited by the MaxRedirects option, but then I
found out that this option had been removed since v2.1 and replaced by
LimitInternalRecursion.
Unfortunately, LimitInternalRecursion doesn't seem to work in this case.
Is this a bug or is it intentionally left as it is? This could cause a lot of
problems in a shared hosting environment. In fact, that's how I found it.
To workaround this problem, I created the following dirty fix:
--- ../httpd-2.2.23-clean/modules/mappers/mod_rewrite.c 2012-08-20
17:22:53.000000000 +0000
+++ modules/mappers/mod_rewrite.c 2012-12-19 11:13:47.701538052 +0000
@@ -1,3 +1,4 @@
+
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -46,6 +47,8 @@
* www.engelschall.com
*/
+#define CORE_PRIVATE
+
#include "apr.h"
#include "apr_strings.h"
#include "apr_hash.h"
@@ -4033,6 +4036,9 @@
int rc;
int s;
rewrite_ctx *ctx;
+ core_server_config *conf =
ap_get_module_config(r->server->module_config, &core_module);
+ int rlimit = conf->redirect_limit ? conf->redirect_limit :
AP_DEFAULT_MAX_INTERNAL_REDIRECTS;
+ int loop_cnt = 0;
ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->perdir = perdir;
@@ -4044,6 +4050,7 @@
entries = (rewriterule_entry *)rewriterules->elts;
changed = 0;
loop:
+ loop_cnt++;
for (i = 0; i < rewriterules->nelts; i++) {
p = &entries[i];
@@ -4116,6 +4123,13 @@
* the rewriting ruleset again.
*/
if (p->flags & RULEFLAG_NEWROUND) {
+ if (loop_cnt > rlimit) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
r->server,
+ "mod_rewrite: Request
exceeded the limit of %d internal "
+ "redirects due to
probable configuration error.", rlimit);
+ break;
+ }
+
goto loop;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]