You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Stratsimir Kolchevski <st...@bastun.net> on 2012/12/19 12:59:23 UTC
[users@httpd] mod_rewrite infinite loop
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: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org