randy 97/01/12 12:01:23
Modified: src CHANGES http_request.c mod_dir.c
Log:
Properly check errno to prevent display of a directory index
when server receives a long enough URL to confuse stat().
Reviewed by: Randy Terbush, Marc Slemko
Submitted by: Marc Slemko
Revision Changes Path
1.119 +3 -0 apache/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.118
retrieving revision 1.119
diff -C3 -r1.118 -r1.119
*** CHANGES 1997/01/12 19:18:46 1.118
--- CHANGES 1997/01/12 20:01:20 1.119
***************
*** 1,5 ****
--- 1,8 ----
Changes with Apache 1.2b5
+ *) Properly check errno to prevent display of a directory index
+ when server receives a long enough URL to confuse stat().
+
*) Several security enhancements to suexec wrapper. It is _highly_
recommended that previously installed versions of the wrapper
be replaced with this version. [Randy Terbush, Jason Dour]
1.36 +39 -6 apache/src/http_request.c
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_request.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -C3 -r1.35 -r1.36
*** http_request.c 1997/01/04 15:10:16 1.35
--- http_request.c 1997/01/12 20:01:21 1.36
***************
*** 125,135 ****
/* OK, it's a symlink. May still be OK with OPT_SYM_OWNER */
! if (!(opts & OPT_SYM_OWNER)) return FORBIDDEN;
! if (stat (d, &fi) < 0) return FORBIDDEN;
! return (fi.st_uid == lfi.st_uid) ? OK : FORBIDDEN;
#endif
}
--- 125,135 ----
/* OK, it's a symlink. May still be OK with OPT_SYM_OWNER */
! if (!(opts & OPT_SYM_OWNER)) return HTTP_FORBIDDEN;
! if (stat (d, &fi) < 0) return HTTP_FORBIDDEN;
! return (fi.st_uid == lfi.st_uid) ? OK : HTTP_FORBIDDEN;
#endif
}
***************
*** 137,143 ****
/* Dealing with the file system to get PATH_INFO
*/
! void get_path_info(request_rec *r)
{
char *cp;
char *path = r->filename;
--- 137,143 ----
/* Dealing with the file system to get PATH_INFO
*/
! int get_path_info(request_rec *r)
{
char *cp;
char *path = r->filename;
***************
*** 155,161 ****
--- 155,164 ----
/* See if the pathname ending here exists... */
*cp = '\0';
+
+ errno = 0;
rv = stat(path, &r->finfo);
+
if (cp != end) *cp = '/';
if (!rv) {
***************
*** 172,180 ****
r->path_info = pstrdup (r->pool, cp);
*cp = '\0';
! return;
}
else {
last_cp = cp;
while (--cp > path && *cp != '/')
--- 175,203 ----
r->path_info = pstrdup (r->pool, cp);
*cp = '\0';
! return OK;
}
+ #if defined(ENOENT)
+ else if (errno == ENOENT) {
+ #else
+ #error ENOENT not defined -- check the comment below this line in the
source for details
+ /*
+ * If ENOENT is not defined in one of the your OS's include
+ * files, Apache does not know how to check to see why the
+ * stat() of the index file failed; there are cases where
+ * it can fail even though the file exists. This means
+ * that it is possible for someone to get a directory
+ * listing of a directory even though there is an index
+ * (eg. index.html) file in it. If you do not have a
+ * problem with this, delete the above #error line and
+ * start the compile again. If you need to do this, please
+ * submit a bug report from http://www.apache.org/bug_report.html
+ * letting us know that you needed to do this. Please be
+ * sure to include the operating system you are using.
+ */
+
else {
+ #endif
last_cp = cp;
while (--cp > path && *cp != '/')
***************
*** 182,189 ****
--- 205,219 ----
while (cp > path && cp[-1] == '/')
--cp;
+ }
+ #if defined(ENOENT)
+ else {
+ log_reason("unable to determine if index file exists (stat()
returned unexpected error)", r->filename, r);
+ return HTTP_FORBIDDEN;
}
+ #endif
}
+ return OK;
}
int directory_walk (request_rec *r)
***************
*** 269,275 ****
no2slash (test_filename);
num_dirs = count_dirs(test_filename);
! get_path_info (r);
if (test_filename[strlen(test_filename)-1] == '/')
--num_dirs;
--- 299,308 ----
no2slash (test_filename);
num_dirs = count_dirs(test_filename);
! res = get_path_info (r);
! if (res != OK) {
! return res;
! }
if (test_filename[strlen(test_filename)-1] == '/')
--num_dirs;
1.19 +2 -2 apache/src/mod_dir.c
Index: mod_dir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_dir.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -C3 -r1.18 -r1.19
*** mod_dir.c 1997/01/01 18:10:31 1.18
--- mod_dir.c 1997/01/12 20:01:21 1.19
***************
*** 693,699 ****
char *tmp;
int dir_opts = find_opts(dir_conf, r);
! if(!(d=opendir(name))) return FORBIDDEN;
r->content_type = "text/html";
--- 693,699 ----
char *tmp;
int dir_opts = find_opts(dir_conf, r);
! if(!(d=opendir(name))) return HTTP_FORBIDDEN;
r->content_type = "text/html";
***************
*** 834,840 ****
if (allow_opts & OPT_INDEXES)
return index_directory (r, d);
else
! return FORBIDDEN;
}
--- 834,840 ----
if (allow_opts & OPT_INDEXES)
return index_directory (r, d);
else
! return HTTP_FORBIDDEN;
}