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";