marc 98/11/08 23:03:20
Modified: src CHANGES src/modules/standard mod_include.c Log: Add more extensive checks to mod_include to avoid infinite recursive includes. The logic used is commented in the source. It should be complete for the current Apache code base, but if something else starts modifying r->filename outside of a filename translation stage that could change. The code scans, at each stage, every subrequest for each level of an internal redirect so it ends up being O(n^2) total in the number of subrequests and internal redirects, but that shouldn't be an issue. PR: 3323 Revision Changes Path 1.1142 +3 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1141 retrieving revision 1.1142 diff -u -r1.1141 -r1.1142 --- CHANGES 1998/11/08 21:24:03 1.1141 +++ CHANGES 1998/11/09 07:03:16 1.1142 @@ -1,5 +1,8 @@ Changes with Apache 1.3.4 + *) SECURITY: Do a more complete check in mod_include to avoid + an infinite loop of recursive SSI includes. [Marc Slemko] PR#3323 + *) Add APACI --suexec-docroot and --suexec-logfile options which can be used to set the document root directory (DOC_ROOT) and the suexec logfile (LOG_EXEC), respectively. Additionally the --layout option 1.106 +33 -5 apache-1.3/src/modules/standard/mod_include.c Index: mod_include.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_include.c,v retrieving revision 1.105 retrieving revision 1.106 diff -u -r1.105 -r1.106 --- mod_include.c 1998/09/24 14:06:42 1.105 +++ mod_include.c 1998/11/09 07:03:19 1.106 @@ -688,13 +688,41 @@ "in parsed file %s"; } if (error_fmt == NULL) { + /* try to avoid recursive includes. We do this by walking + * up the r->main list of subrequests, and at each level + * walking back through any internal redirects. At each + * step, we compare the filenames and the URIs. + * + * The filename comparison catches a recursive include + * with an ever-changing URL, eg. + * <!--#include virtual= + * "$REQUEST_URI/$QUERY_STRING?$QUERY_STRING/x"--> + * which, although they would eventually be caught because + * we have a limit on the length of files, etc., can + * recurse for a while. + * + * The URI comparison catches the case where the filename + * is changed while processing the request, so the + * current name is never the same as any previous one. + * This can happen with "DocumentRoot /foo" when you + * request "/" on the server and it includes "/". + * This only applies to modules such as mod_dir that + * (somewhat improperly) mess with r->filename outside + * of a filename translation phase. + */ + int founddupe = 0; request_rec *p; + for (p = r; p != NULL && !founddupe; p = p->main) { + request_rec *q; + for (q = p; q != NULL; q = q->prev) { + if ( (strcmp(q->filename, rr->filename) == 0) || + (strcmp(q->uri, rr->uri) == 0) ){ + founddupe = 1; + break; + } + } + } - for (p = r; p != NULL; p = p->main) { - if (strcmp(p->filename, rr->filename) == 0) { - break; - } - } if (p != NULL) { error_fmt = "Recursive include of \"%s\" " "in parsed file %s";