Commit ab34ae21 authored by Ruediger Pluem's avatar Ruediger Pluem
Browse files

* 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
parent 14a80e37
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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]
+34 −1
Original line number Diff line number Diff line
@@ -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;
        }