httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Petr Lampa <la...@fee.vutbr.cz>
Subject [PATCH] "Type Map file bug causes 100% CPU and mem leak"
Date Wed, 12 Mar 1997 22:09:53 GMT
> Submitter: weave@dtcc.edu
> Operating system: OTHER:DG/UX, version: 4.11
> Version of Apache Used: 1.2B7
> Extra Modules used: None
> URL exhibiting problem: Not on your life! :)
> 
> Symptoms:
> --
> If a trailing slash is included after a type map
> file URL, apache goes into a constant write state,
> dropping the connection doesn't stop it, it consumes
> 100% of CPU, and a huge memory leak starts.
> 
> I tried to reproduce it successfully on a Linux 
> box running the RedHat distribution (apache 1.1.1)
> 
> In this case, it hung the entire system. This is
> a dual-pentium so it shouldn't have consumed BOTH
> CPUs... 
> --

Confirmed. It's in handle_map_file() (mod_negotiation.c):
   ...
   udir = make_dirstr (r->pool, r->uri, count_dirs (r->uri));
   udir = escape_uri(r->pool, udir);
   internal_redirect (make_full_path (r->pool, udir, best->file_name), r);
   return OK;

request is "GET /tst.var/", where /tst.var is map file, then
r->uri = "/tst.var/" -> count_dirs(r->uri) is 2 -> udir = "/tst.var/"
best->file_name = tst2.html
make_full_path (new uri) = "/tst.var/tst2.html"

This redirection enters handle_map_file() again, and the situation repeats
indefinitely (until stack overflows). 

Proposed solution is:

***************
*** 1865,1873 ****
      if (na_result == na_not_applied)
          set_neg_headers(r, neg, na_not_applied);

      udir = make_dirstr (r->pool, r->uri, count_dirs (r->uri));
      udir = escape_uri(r->pool, udir);
!     internal_redirect (make_full_path (r->pool, udir, best->file_name), r);
      return OK;
  }

--- 1875,1886 ----
      if (na_result == na_not_applied)
          set_neg_headers(r, neg, na_not_applied);

+     if (r->path_info && *r->path_info) {
+         r->uri[find_path_info(r->uri, r->path_info)] = '\0';
+     }
      udir = make_dirstr (r->pool, r->uri, count_dirs (r->uri));
      udir = escape_uri(r->pool, udir);
!     internal_redirect (pstrcat(r->pool, udir, best->file_name, r->path_info, NULL),
r);
 return OK;

Discussion:
- first part takes out path_info from r->uri (taken from add_cgi_vars())
- second part generates new full uri with negotiated file name and path_info.
  (in the example above new_uri="/tst2.html/", which is wrong if /tst2.html
  is file and the error response is properly returned).
  It's not necessary to use make_full_path, since udir always contains "/" 
  at the end (see make_dirstr).

I am attaching my previous fix for mod_negotiation with this one.
Ooops, one more fix - it's necessary to make find_path_info() in
util_script.c global! (second diff for util_script.c).

+++
And one more question: it's quite possible to cause such negotiation
loop with bad map file. The existence of the file specified 
in the "uri:" directive in map file is not verified and redirection
to this file may result in another negotiation. What about verifying
existence of the file using stat() and ignoring such variant, 
if file doesn't exist?

							Petr

-- 
Department of Computer Science and Engineering  E-mail: lampa@fee.vutbr.cz
Faculty of El. Engineering and Comp. Science	Phone: (+420 5) 7275/225,111
Technical University of Brno			Fax:  (+420 5) 41211141
Bozetechova 2, 612 66 Brno, Czech Republic

Mime
View raw message