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