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