]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* Check for symbolic links of the target file in the optimized case that we
authorRuediger Pluem <rpluem@apache.org>
Thu, 20 Jul 2006 11:01:07 +0000 (11:01 +0000)
committerRuediger Pluem <rpluem@apache.org>
Thu, 20 Jul 2006 11:01:07 +0000 (11:01 +0000)
  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

CHANGES
server/request.c

diff --git a/CHANGES b/CHANGES
index 0ec3be54635bc070cbb57346e9b272e5ccfe22a4..c853a8fddbbe12e77041b137886ac3a18a9e572f 100644 (file)
--- 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]
 
index ac139a089547bcb0a73e0415c0b6b20f49d16a2c..5af0c921c2c40df8a11f711910aff71068954740 100644 (file)
@@ -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;
         }