From: Ruediger Pluem Date: Thu, 20 Jul 2006 11:01:07 +0000 (+0000) Subject: * Check for symbolic links of the target file in the optimized case that we X-Git-Tag: 2.3.0~2240 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=356d882a5dee67daa6ad2f6a57703d7a046af787;p=thirdparty%2Fapache%2Fhttpd.git * Check for symbolic links of the target file in the optimized case that we had already done this specific directory walk for this request. This can happen when we have an internal redirect, like the ones caused by mod_dir (/ -> index.html). See also http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/%3c44B5521F.8050906@globalvanet.com%3e Reviewed by: wrowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@423886 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0ec3be54635..c853a8fddbb 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,11 @@ Changes with Apache 2.3.0 [Remove entries to the current 2.0 and 2.2 section below, when backported] + *) SECURITY: + core: Do not allow internal redirects like the DirectoryIndex of mod_dir + to circumvent the symbolic link checks imposed by FollowSymLinks and + SymLinksIfOwnerMatch. [Nick Kew, Ruediger Pluem, William Rowe] + *) mod_proxy: Support environment variable interpolation in reverse proxying directives [Nick Kew] diff --git a/server/request.c b/server/request.c index ac139a08954..5af0c921c2c 100644 --- a/server/request.c +++ b/server/request.c @@ -524,17 +524,50 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) && (!r->path_info || !*r->path_info))) && (cache->dir_conf_tested == sec_ent) && (strcmp(entry_dir, cache->cached) == 0)) { + int familar = 0; + /* Well this looks really familiar! If our end-result (per_dir_result) * didn't change, we have absolutely nothing to do :) * Otherwise (as is the case with most dir_merged/file_merged requests) * we must merge our dir_conf_merged onto this new r->per_dir_config. */ if (r->per_dir_config == cache->per_dir_result) { - return OK; + familar = 1; } if (r->per_dir_config == cache->dir_conf_merged) { r->per_dir_config = cache->per_dir_result; + familar = 1; + } + + if (familar) { + apr_finfo_t thisinfo; + int res; + allow_options_t opts; + core_dir_config *this_dir; + + this_dir = ap_get_module_config(r->per_dir_config, &core_module); + opts = this_dir->opts; + /* + * If Symlinks are allowed in general we do not need the following + * check. + */ + if (!(opts & OPT_SYM_LINKS)) { + apr_stat(&thisinfo, r->filename, + APR_FINFO_MIN | APR_FINFO_NAME | APR_FINFO_LINK, + r->pool); + if (thisinfo.filetype == APR_LNK) { + /* Is this a possibly acceptable symlink? */ + if ((res = resolve_symlink(r->filename, &thisinfo, + opts, r->pool)) != OK) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Symbolic link not allowed " + "or link target not accessible: %s", + r->filename); + return r->status = res; + } + } + } return OK; }